3. Distribution of Individual Features
To prepare the dataset for our analysis purpose, we utilized the sample
function to create some missingness in our dataset. We randomly replaced
5% of all feature variables with missing values to make the dataset
represent real world data which is often observed with missing values in
variables. It is important to point out that since this is an already
cleaned dataset, there are not much to be done in addressing issues like
unlikely values ( extreme height or weight, etc, non standard response
to questionnaires among others). We will utilize exploratory data
analysis to uncover patterns and relationships in the dataset. Feature
engineering will be applied where applicable to create new variables and
a visual representation of the data will be provided to identify trends
and feature variable distributions. Additionally, sub group
visualizations will be presented that enlightens our understanding of
how diabetes affects certain groups of people and which feature
variables are associated with diabetes.
- Individual analytic tasks - The following feature
variables comprise of some of the risk factors that are reported to be
associated with diabetes that will be studied.
- BMI: BMI histogram showed positively skewed data while a box plot
also showed outliers. The outliers were removed from the dataset that
were 1.5 times lower or higher than the first and third quartiles. The
plot of the data without the outliers showed a smoother distribution.
BMI was re-categorized into Underweight, Normal, Overweight and Obese.
Over 70% of the sample were either overweight or obese to help identify
at risk populations and easier interpretation of the data and for trend
identification. It was apparent that most of the participants where
either over weight or obese.
library(dplyr)
ddat <- read.csv("https://matuahene.github.io/STA552/Week%202/diabetes_binary_health_indicators_BRFSS2015.csv", skip=0)
ddat$Income_cat <- cut(ddat$Income,
breaks = c(-Inf, 3, 5, 6, Inf),
labels = c("Low", "Medium", "High", "Very High"))
ddat2 <-ddat
ddat2$Age <- factor(ddat2$Age,
levels = 1:13,
labels = c("18-24 yrs", "25-29 yrs", "30-34 yrs", "35-39 yrs", "40-44 yrs",
"45-49 yrs", "50-54 yrs", "55-59 yrs", "60-64 yrs", "65-69 yrs",
"70-74 yrs", "75-79 yrs", "80+ yrs"))
ddat2 <- ddat2 %>%
mutate(BMI_Cat = cut(BMI,
breaks = c(0, 18.5, 24.9, 29.9, Inf),
labels = c("Underweight", "Normal", "Overweight", "Obese")))
ddat2 <- ddat2 %>%
mutate(
HighChol = recode(HighChol, "0" = "No", "1" = "Yes"),
HighBP = recode(HighBP, "0" = "No", "1" = "Yes"),
Smoker = recode(Smoker, "0" = "No", "1" = "Yes"),
Stroke = recode(Stroke, "0" = "No", "1" = "Yes"),
HeartDiseaseorAttack = recode(HeartDiseaseorAttack, "0" = "No", "1" = "Yes"),
PhysActivity = recode(PhysActivity, "0" = "No", "1" = "Yes"),
Fruits = recode(Fruits, "0" = "No", "1" = "Yes"),
Veggies = recode(Veggies, "0" = "No", "1" = "Yes")
)
ddat2 <- ddat2 %>%
mutate(
Education = recode(Education,
"1" = "No High School",
"2" = "Some High School",
"3" = "High School Graduate",
"4" = "Some College",
"5" = "College Graduate",
"6" = "College 4 years or more (College graduate)"),
Income = recode(Income,
"1" = "<$10K",
"2" = "$10K-$15K",
"3" = "$15K-$25K",
"4" = "$25K-$35K",
"5" = "$35K-$50K",
"6" = "$50K-$75K",
"7" = ">$75K",
.default = "Unknown"),
Sex = recode(Sex,
"1" = "Male",
"0" = "Female",
.default = "Unknown"),
CholCheck = recode(CholCheck,
"1" = "Yes",
"0" = "No" ),
DiffWalk = recode(DiffWalk,
"1" = "Yes",
"0" = "No" ),
AnyHealthcare = recode(AnyHealthcare,
"1" = "Yes",
"0" = "No" ),
NoDocbcCost = recode(NoDocbcCost,
"1" = "Yes",
"0" = "No" ),
HvyAlcoholConsump = recode(HvyAlcoholConsump,
"1" = "Yes",
"0" = "No" ),
Diabetes_binary = recode(Diabetes_binary,
"0" = "No Diabetes",
"1" = "Has Diabetes"),
GenHlth = recode(GenHlth,
"1" = "Excellent",
"2" = "Very Good",
"3" = "Good",
"4" = "Fair",
"5" = "Poor",
.default = "Unknown")
)
missing_percentage <- 0.05
total_rows <- nrow(ddat2)
ddat2 <- ddat2 %>%
mutate(across(everything(), ~ {
miss_id <- sample(1:total_rows, size = round(missing_percentage * total_rows), replace = FALSE)
.[miss_id] <- NA
.
}))
library(summarytools)
dfSummary(ddat2)
library(ggplot2)
library(gridExtra)
library(grid)
bmi1 <- ggplot(ddat2, aes(x = BMI)) +
geom_histogram(binwidth = 2, fill = "steelblue", color = "black", alpha = 0.7) +
labs(title = "BMI Distribution", x = "BMI", y = "Count") +
theme_minimal()
bmi2 <- ggplot(ddat2, aes(x = BMI)) +
geom_density(fill = "lightblue", alpha = 0.6) +
labs(title = "Density Plot of BMI", x = "BMI", y = "Density") +
theme_minimal()
bmi3 <- ggplot(ddat2, aes(y = BMI)) +
geom_boxplot(fill = "tomato", alpha = 0.7, outlier.color = "red") +
labs(title = "Boxplot of BMI", y = "BMI") +
theme_minimal()
grid.arrange(bmi1, bmi2, bmi3, ncol = 2, top = textGrob("Overview of BMI", gp = gpar(fontsize = 16, fontface = "bold")))

library(e1071)
skewness(ddat2$BMI, na.rm=TRUE)
skewness(ddat2$BMI, na.rm=TRUE)
Q1 <- quantile(ddat2$BMI, 0.25, na.rm = TRUE)
Q3 <- quantile(ddat2$BMI, 0.75, na.rm = TRUE)
IQR <- Q3 - Q1
lower_bound <- Q1 - 1.5 * IQR
upper_bound <- Q3 + 1.5 * IQR
ddat3 <- ddat2[ddat2$BMI >= lower_bound & ddat2$BMI <= upper_bound, ]
bmi12 <- ggplot(ddat3, aes(x = BMI)) +
geom_histogram(binwidth = 2, fill = "steelblue", color = "black", alpha = 0.7) +
labs(title = "BMI Distribution", x = "BMI", y = "Count") +
theme_minimal()
bmi22 <- ggplot(ddat3, aes(x = BMI)) +
geom_density(fill = "lightblue", alpha = 0.6) +
labs(title = "Density Plot of BMI", x = "BMI", y = "Density") +
theme_minimal()
bmi32 <- ggplot(ddat3, aes(y = BMI)) +
geom_boxplot(fill = "tomato", alpha = 0.7, outlier.color = "red") +
labs(title = "Boxplot of BMI", y = "BMI") +
theme_minimal()
grid.arrange(bmi12, bmi22, bmi32, ncol = 2, top = textGrob("Overview of BMI with no outliers", gp = gpar(fontsize = 16, fontface = "bold")))

bmigrp<- ggplot(ddat3 %>% filter(!is.na(BMI_Cat)), aes(x = BMI_Cat)) +
geom_bar(fill = "lightblue" , width = 0.6) +
labs(title = "BMI Categories Distribution",
x = "BMI category",
y = "Count"
) +
theme_classic() +
theme(plot.margin = margin(2, 2, 2, 2) )
bmigrp

- Diabetes Status: In the sample, majority of the participants did not
have diabetes(86%). Only a smaller proportion where diabetic or had
pre-diabetes. This suggests low prevalence of diabetes in our
sample.
- Mental Health: Histogram and density plots showed few people had few
days with poor mental health the last 30 days (mean = approximately 3
days of bad mental health days). Outliers were replaced with mean
values.
- Physical Health in last 30 days distribution showed outliers and
these values were replaced with the mean.
- General Health Status: Most people reported very good or good health
status overall with skewness observed towards poor health. and so no
special changes will be applied to the variable.
- Income variable was negatively skewed. Most participants earned
higher income. The variable is categorized into Low, Medium, and High
income levels.
- Sex: More females participated in the sample data than males.
- Age: Distribution of age was such that majority of participants were
beyond 40 years old. This suggests that most participants were older and
age should controlled for in any analysis.
- Education: Most of the participants had a high school diploma or
higher (over 80%).
- High blood Pressure and High Cholesterol: More participants did not
have high blood pressure and more did not have any cholesterol checks in
the last 5 years.
- Smoker: About 44% of the participants smoked at least 100 cigarettes
in their entire lifetime. Considering how smoking affects our health and
with such many in sample, controlling for this variable in our analysis
and exploring how this variable interacts with others to impact diabetes
will be studied.
- Heavy Alcohol consumption - both men and women reported they are not
heavy drinkers but these could be incorrect representation due to the
fact that they may report as not heavy drinkers for socially desirable
responses and expectations. The analysis can be conducted for men and
women separately and for those who reported as heavy drinkers to uncover
hidden relations.
- Heart disease/attack was not prevalent in our sample. But we know
that diabetes impacts the heart function, it will be interesting to see
if those who had diabetes reported to ave had any of these
conditions.
- Stroke: Most people had never been told they had diabetes
(95%).
- Other variables: Most people did not have difficulty walking up the
stairs, were physically active in the past 30 days, had some form of
health insurance and could see a doctor when needed, consumed vegetables
once or more times a day, but slightly more did not consume fruits at
the same rate as vegetables.
ggplot(ddat3 %>% filter(!is.na(Diabetes_binary)), aes(x = factor(Diabetes_binary))) +
geom_bar(fill = "lightblue" , width = 0.4) +
labs(title = "Diabetes Status",
x = "Diabetes Status",
y = "Count"
) +
theme_classic()+
theme(plot.margin = margin(2, 2, 2, 2) )

Diab.percentages <- ddat3 %>%
count(Diabetes_binary) %>%
mutate(Percentage = n / sum(n) * 100)
Diab.percentages
summary(ddat3$MentHlth)
menh1 <- ggplot(ddat2, aes(x = MentHlth)) +
geom_density(fill = "yellow", alpha = 0.6) +
labs(title = "Density Plot of not good mental health days", x = "Mental Health", y = "Density") +
theme_minimal()
menh2 <- ggplot(ddat3, aes(x = MentHlth)) +
geom_histogram(binwidth = 2, fill = "yellow", color = "black", alpha = 0.7) +
labs(title = "Histogram of not good mental health days", x = "Days", y = "Count") +
theme_minimal()
menh3 <- ggplot(ddat3, aes(y = MentHlth)) +
geom_boxplot(fill = "yellow", alpha = 0.7, outlier.color = "red") +
labs(title = "Boxplot of Number of days Mental health was not good", y = "Mental Health Days") +
theme_minimal()
grid.arrange(menh1, menh2, menh3, ncol = 2, top = textGrob("Overview of Mental Health in Past 30 Days", gp = gpar(fontsize = 16, fontface = "bold")))

replace_outliers_with_mean <- function(x) {
Q1 <- quantile(x, 0.25, na.rm = TRUE)
Q3 <- quantile(x, 0.75, na.rm = TRUE)
IQR <- Q3 - Q1
lower_bound <- Q1 - 1.5 * IQR
upper_bound <- Q3 + 1.5 * IQR
x[x < lower_bound | x > upper_bound] <- mean(x, na.rm = TRUE)
return(x)
}
ddat3$MentHlth <- replace_outliers_with_mean(ddat3$MentHlth)
Ph <- ggplot(ddat3, aes(x = PhysHlth)) +
geom_histogram(binwidth = 2, fill = "steelblue", color = "black", alpha = 0.7) +
labs(title = "Physical Health Days", x = "Days", y = "Count") +
theme_minimal()
ddat3$PhysHlth <- replace_outliers_with_mean(ddat3$PhysHlth)
ddat3 <- ddat3 %>%
mutate(GenHlth = factor(GenHlth,
levels = c("Poor", "Fair", "Good", "Very Good", "Excellent"),
ordered = TRUE))
Gh <- ggplot(ddat3 %>% filter(!is.na(GenHlth)), aes(x = GenHlth)) +
geom_bar(fill = "blue", width =0.4) +
labs(title = "General Health Status",
x = "General Health",
y = "Count"
) +
scale_x_discrete(expand = c(0.1, 0.1))+
theme_classic()
Gh

Sex <- ggplot(ddat3 %>% filter(!is.na(Sex)), aes(x = Sex)) +
geom_bar(fill = "blue") +
labs(title = "Gender",
x = "Gender",
y = "Count"
) +
theme_classic()
unique(ddat3$Sex);
Age <- ggplot(ddat2 %>% filter(!is.na(Age)), aes(x = Age)) +
geom_bar(fill = "blue") +
labs(title = "Age group Bar Chart",
x = "Age Group",
y = "Count"
) +
theme_classic()
Age.percentages <- ddat %>%
count(Age) %>%
mutate(Percentage = n / sum(n) * 100)
Age.percentages
Edu.percentages <- ddat %>%
count(Education) %>%
mutate(Percentage = n / sum(n) * 100)
Edu.percentages
Smoke.percentages <- ddat %>%
count(Smoker) %>%
mutate(Percentage = n / sum(n) * 100)
Smoke.percentages
Stroke.percentages <- ddat %>%
count(Stroke) %>%
mutate(Percentage = n / sum(n) * 100)
Stroke.percentages
4. Relationship between Features - Bivariate
We will now explore and have visualizations of relationships among
several variables in our sample data. We will be looking at visuals for
two or more numerical feature variables, categorical variables and
visuals that look combinations of these to aid in our understanding of
the data and how it influences our understanding of how to approach
analysis of the data.
- Diabetes and BMI plots : The box plot showing the diabetes and BMI
plot shows the median BMI in the diabetic group is higher suggests
relationship between these 2 variables. Additionally, the density plot
shows higher BMI in the diabetic group than the non-diabetic group.
- Diabetes and Physical Activity plot: The bivariate plot shows that
while the distribution of physical activity in the past 30 days is
similar, far less
diabetic people were physically active in the last 30 days.
ggplot(ddat3%>% filter(!is.na(Diabetes_binary)), aes(x = factor(Diabetes_binary), y = BMI, fill = factor(Diabetes_binary))) +
geom_boxplot() +
labs(title = "BMI Distribution by Diabetes Status",
x = "Diabetes Status",
y = "BMI") +
scale_fill_manual(values = c("red", "green")) +
theme_classic()+
theme(legend.title = element_blank())

ggplot(ddat3%>% filter(!is.na(Diabetes_binary)), aes(x = BMI, fill = factor(Diabetes_binary))) +
geom_density(alpha = 0.5) +
labs(title = "BMI Density Plot by Diabetes Status",
x = "BMI",
y = "Density") +
scale_fill_manual(values = c("red", "green")) +
theme_minimal()+
theme(legend.title = element_blank())

ggplot(ddat3%>% filter(!is.na(Diabetes_binary) & !is.na(PhysActivity)), aes(x = factor(Diabetes_binary), fill = factor(PhysActivity))) +
geom_bar(position = "dodge") +
labs(title = "Grouped Bar Plot of Diabetes Status and Physical Activity in pas 30 days",
x = "Diabetes Status",
y = "Count") +
scale_fill_manual(values = c("blue", "red", "green")) +
guides(fill = guide_legend(title = "Pysically Active last 30 days")) +
theme_classic()

library(ggcorrplot)
select_vars <- c("PhysHlth", "MentHlth", "GenHlth", "BMI")
corr_matrix <- cor(ddat %>% select(all_of(select_vars)), use = "complete.obs")
library(ggplot2)
library(reshape2)
corr_melt <- melt(corr_matrix)
cor1 <- ggplot(corr_melt, aes(x = Var1, y = Var2, fill = value)) +
geom_tile() +
geom_text(aes(label = round(value, 2)), color = "black", size = 4) +
scale_fill_gradient2(low = "blue", mid = "white", high = "red", midpoint = 0) +
theme_minimal() +
labs(title = "Correlation Heatmap", fill = "Correlation") +
theme(axis.text.x = element_text(angle = 45, hjust = 1))
library(corrplot)
corrplot(corr_matrix, method = "color", type = "upper",
col = colorRampPalette(c("blue", "white", "red"))(200),
tl.cex = 0.7, tl.col = "black",
addCoef.col = "black", number.cex = 0.8)

library(ggplot2)
library(plotly)
unique(ddat3$Income_cat)
[1] Low Very High <NA> Medium High
Levels: Low Medium High Very High
mycolors <- c("Low" = "red", "Medium" = "orange", "High" = "green", "Very High" = "blue")
ggplotly_density <- ddat3%>% filter(!is.na(Income_cat) & !is.na(Diabetes_binary)) %>%
ggplot(aes(x = BMI, color = Income_cat, fill = Income_cat)) +
geom_density(linewidth = 0.75, alpha = 0.6) +
xlab("BMI Index") +
labs(color = "Income Groups", fill = "Income Groups") +
ggtitle("Density Curve of BMI across Income Groups") +
scale_color_manual(values = mycolors) +
scale_fill_manual(values = mycolors) +
theme(plot.margin = unit(c(2,1,2,1), "cm"),
plot.title = element_text(hjust = 0.5)) +
facet_wrap(~ Diabetes_binary)
ggplotly(ggplotly_density)
mycolors.n <- c("Poor" = "red", "Fair" = "orange", "Good" = "green", "Very Good" = "blue", "Excellent" = "lightblue")
ggplotly_density.n <- ddat3%>% filter(!is.na(GenHlth) & !is.na(Diabetes_binary)) %>%
ggplot(aes(x = BMI, color = GenHlth, fill = GenHlth)) +
geom_density(linewidth = 0.75, alpha = 0.6) +
xlab("BMI Index") +
labs(color = "General Health", fill = "General Health") +
ggtitle("Density Curve of BMI across General Health") +
scale_color_manual(values = mycolors.n) +
scale_fill_manual(values = mycolors.n) +
theme(plot.margin = unit(c(2,1,2,1), "cm"),
plot.title = element_text(hjust = 0.5)) +
facet_wrap(~ Diabetes_binary)
ggplotly(ggplotly_density.n)
LS0tCnRpdGxlOiAiSWRlbnRpZmljYXRpb24gb2YgRmFjdG9ycyBBc3NvY2ljYXRlZCB3aXRoIERpYWJldGVzIGluIHRoZSBVU0EiCiNzdWJ0aXRsZTogIkJlaGF2aW9yYWwgUmlzayBGYWN0b3IgU3VydmVpbGxhbmNlIFN5c3RlbSAoQlJGU1MpIgphdXRob3I6ICJNZXJjeSBBdHVhaGVuZSIgCmRhdGU6ICJGZWJydWFyeSA1LCAyMDI1IgphZmZpbGlhdGlvbjogIldlc3QgQ2hlc3RlciBVbml2ZXJzaXR5IG9mIFBlbm5zeWx2YW5pYSwgRGVwYXJ0bWVudCBvZiBTdGF0aXN0aWNzIgpvdXRwdXQ6CiAgaHRtbF9kb2N1bWVudDogCiAgICB0b2M6IHllcwogICAgdG9jX2RlcHRoOiA0CiAgICB0b2NfZmxvYXQ6IHllcwogICAgbnVtYmVyX3NlY3Rpb25zOiBubwogICAgdG9jX2NvbGxhcHNlZDogeWVzCiAgICBjb2RlX2ZvbGRpbmc6IGhpZGUKICAgIGNvZGVfZG93bmxvYWQ6IHllcwogICAgc21vb3RoX3Njcm9sbDogeWVzCiAgICB0aGVtZTogbHVtZW4KIAogIHdvcmRfZG9jdW1lbnQ6IAogICAgdG9jOiB5ZXMKICAgIHRvY19kZXB0aDogNAogICAgZmlnX2NhcHRpb246IHllcwogICAga2VlcF9tZDogeWVzCiAgcGRmX2RvY3VtZW50OiAKICAgIHRvYzogeWVzCiAgICB0b2NfZGVwdGg6IDQKICAgIGZpZ19jYXB0aW9uOiB5ZXMKICAgIG51bWJlcl9zZWN0aW9uczogbm8KICAgIGZpZ193aWR0aDogMwogICAgZmlnX2hlaWdodDogMwplZGl0b3Jfb3B0aW9uczogCiAgY2h1bmtfb3V0cHV0X3R5cGU6IGlubGluZQotLS0KCmBgYHs9aHRtbH0KCjxzdHlsZSB0eXBlPSJ0ZXh0L2NzcyI+CgovKiBDYXNjYWRpbmcgU3R5bGUgU2hlZXRzIChDU1MpIGlzIGEgc3R5bGVzaGVldCBsYW5ndWFnZSB1c2VkIHRvIGRlc2NyaWJlIHRoZSBwcmVzZW50YXRpb24gb2YgYSBkb2N1bWVudCB3cml0dGVuIGluIEhUTUwgb3IgWE1MLiBpdCBpcyBhIHNpbXBsZSBtZWNoYW5pc20gZm9yIGFkZGluZyBzdHlsZSAoZS5nLiwgZm9udHMsIGNvbG9ycywgc3BhY2luZykgdG8gV2ViIGRvY3VtZW50cy4gKi8KCmgxLnRpdGxlIHsgIC8qIFRpdGxlIC0gZm9udCBzcGVjaWZpY2F0aW9ucyBvZiB0aGUgcmVwb3J0IHRpdGxlICovCiAgZm9udC1zaXplOiAyMnB4OwogIGZvbnQtd2VpZ2h0OiBib2xkOwogIGNvbG9yOiBEYXJrUmVkOwogIHRleHQtYWxpZ246IGNlbnRlcjsKICBmb250LWZhbWlseTogIkdpbGwgU2FucyIsIHNhbnMtc2VyaWY7Cn0KaDQuYXV0aG9yIHsgLyogSGVhZGVyIDQgLSBmb250IHNwZWNpZmljYXRpb25zIGZvciBhdXRob3JzICAqLwogIGZvbnQtc2l6ZTogMThweDsKICBmb250LXdlaWdodDogYm9sZDsKICBmb250LWZhbWlseTogc3lzdGVtLXVpOwogIGNvbG9yOiBuYXZ5OwogIHRleHQtYWxpZ246IGNlbnRlcjsKfQpoNC5kYXRlIHsgLyogSGVhZGVyIDQgLSBmb250IHNwZWNpZmljYXRpb25zIGZvciB0aGUgZGF0ZSAgKi8KICBmb250LXNpemU6IDE4cHg7CiAgZm9udC1mYW1pbHk6IHN5c3RlbS11aTsKICBjb2xvcjogRGFya0JsdWU7CiAgdGV4dC1hbGlnbjogY2VudGVyOwogIGZvbnQtd2VpZ2h0OiBib2xkOwp9CmgxIHsgLyogSGVhZGVyIDEgLSBmb250IHNwZWNpZmljYXRpb25zIGZvciBsZXZlbCAxIHNlY3Rpb24gdGl0bGUgICovCiAgICBmb250LXNpemU6IDE4cHg7CiAgICBmb250LWZhbWlseTogIkdpbGwgU2FucyIsIHNhbnMtc2VyaWY7CiAgICBjb2xvcjogbmF2eTsKICAgIHRleHQtYWxpZ246IGNlbnRlcjsKICAgIGZvbnQtd2VpZ2h0OiBib2xkOwp9CmgyIHsgLyogSGVhZGVyIDIgLSBmb250IHNwZWNpZmljYXRpb25zIGZvciBsZXZlbCAyIHNlY3Rpb24gdGl0bGUgKi8KICAgIGZvbnQtc2l6ZTogMTZweDsKICAgIGZvbnQtZmFtaWx5OiAiR2lsbCBTYW5zIiwgc2Fucy1zZXJpZjsKICAgIGNvbG9yOiBuYXZ5OwogICAgdGV4dC1hbGlnbjogbGVmdDsKICAgIGZvbnQtd2VpZ2h0OiBib2xkOwp9CgoKaDMgeyAvKiBIZWFkZXIgMyAtIGZvbnQgc3BlY2lmaWNhdGlvbnMgb2YgbGV2ZWwgMyBzZWN0aW9uIHRpdGxlICAqLwogICAgZm9udC1zaXplOiAxNHB4OwogICAgZm9udC1mYW1pbHk6ICJHaWxsIFNhbnMiLCBzYW5zLXNlcmlmOwogICAgY29sb3I6IG5hdnk7CiAgICB0ZXh0LWFsaWduOiBsZWZ0Owp9CgpoNCB7IC8qIEhlYWRlciA0IC0gZm9udCBzcGVjaWZpY2F0aW9ucyBvZiBsZXZlbCA0IHNlY3Rpb24gdGl0bGUgICovCiAgICBmb250LXNpemU6IDEycHg7CiAgICBmb250LWZhbWlseTogIkdpbGwgU2FucyIsIHNhbnMtc2VyaWY7CiAgICBjb2xvcjogZGFya3JlZDsKICAgIHRleHQtYWxpZ246IGxlZnQ7Cn0KCmJvZHkgeyBiYWNrZ3JvdW5kLWNvbG9yOndoaXRlOyB9CgouaGlnaGxpZ2h0bWUgeyBiYWNrZ3JvdW5kLWNvbG9yOnllbGxvdzsgfQoKcCB7IGJhY2tncm91bmQtY29sb3I6d2hpdGU7IH0KCjwvc3R5bGU+CmBgYAoKYGBge3Igc2V0dXAsIGluY2x1ZGU9RkFMU0V9CgojIGNvZGUgY2h1bmsgc3BlY2lmaWVzIHdoZXRoZXIgdGhlIFIgY29kZSwgd2FybmluZ3MsIGFuZCBvdXRwdXQgCiMgd2lsbCBiZSBpbmNsdWRlZCBpbiB0aGUgb3V0cHV0IGZpbGVzLgppZiAoIXJlcXVpcmUoImtuaXRyIikpIHsKICAgaW5zdGFsbC5wYWNrYWdlcygia25pdHIiKQogICBsaWJyYXJ5KGtuaXRyKQp9CmlmICghcmVxdWlyZSgidGlkeXZlcnNlIikpIHsKICAgaW5zdGFsbC5wYWNrYWdlcygidGlkeXZlcnNlIikKbGlicmFyeSh0aWR5dmVyc2UpCn0KaWYgKCFyZXF1aXJlKCJHR2FsbHkiKSkgewogICBpbnN0YWxsLnBhY2thZ2VzKCJHR2FsbHkiKQpsaWJyYXJ5KEdHYWxseSkKfQprbml0cjo6b3B0c19jaHVuayRzZXQoZWNobyA9IFRSVUUsICAgIyBpbmNsdWRlIGNvZGUgY2h1bmsgaW4gdGhlIG91dHB1dCBmaWxlCiAgICAgICAgICAgICAgICAgICAgICB3YXJuaW5nID0gRkFMU0UsIyBzb21ldGltZXMsIHlvdSBjb2RlIG1heSBwcm9kdWNlIHdhcm5pbmcgbWVzc2FnZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyB5b3UgY2FuIGNob29zZSB0byBpbmNsdWRlIHRoZSB3YXJuaW5nIG1lc3NhZ2VzIGluCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyB0aGUgb3V0cHV0IGZpbGUuIAogICAgICAgICAgICAgICAgICAgICAgcmVzdWx0cyA9IFRSVUUsICMgeW91IGNhbiBhbHNvIGRlY2lkZSB3aGV0aGVyIHRvIGluY2x1ZGUgdGhlIG91dHB1dAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgaW4gdGhlIG91dHB1dCBmaWxlLgogICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZSA9IEZBTFNFLAogICAgICAgICAgICAgICAgICAgICAgY29tbWVudCA9IE5BCiAgICAgICAgICAgICAgICAgICAgICApICAKI3NldHdkKCJ+IikKI3NldHdkKCIvVXNlcnMvbWthdHVhaGVuZS9EZXNrdG9wL1dDVS9SLU1hY2hpbmUgTGVhcm5pbmcvQXNzaWdubWVudC9XZWVrIDIiKSAKYGBgCgpcCgojIyAxLiBBYnN0cmFjdApUaGlzIGFuYWx5c2lzIHN0dWRpZXMgdGhlIHJlbGF0aW9uc2hpcHMgYW1vbmcgaGVhbHRoIGluZGljYXRvcnMgYW5kIGRpYWJldGVzIHN0YXR1cyB2aWEgZXhwbG9yYXRvcnkgZGF0YSBhbmFseXNpcyB2aXN1YWxpemF0aW9ucy4gSXQgaXMgYmFzZWQgb24gYSBzYW1wbGUgZGF0YSBmcm9tIHRoZSBEaWFiZXRlcyBIZWFsdGggSW5kaWN0b3JzIGRhdGFzZXQgKEJSRlNTIDIwMTUpLiBXZSBmaXJzdCB1c2UgdmlzdWFsaXphdGlvbiBtZXRob2RzIHRvIGxvb2sgYXQgaW5kaXZpZHVhbCB2YXJpYWJsZSBkaXN0cmlidXRpb25zIGFuZCB0aGVuIGV4YW1pbmUgYXNzb2NpYXRpb25zIGJldHdlZW4gZGlmZmVyZW50IHR5cGVzIG9mIHZhcmlhYmxlcyBsaWtlIGRpYWJldGVzIHN0YXR1cyBhbmQgQk1JIHRocm91Z2ggaGlzdG9ncmFtcywgYm94IHBsb3RzIGFuZCBkZW5zaXR5IHBsb3RzLiBXZSBhbHNvIGV4cGxvcmVkIHJlbGF0aW9ucyBiZXR3ZWVuIG51bWVyaWNhbCB2YXJpYWJsZXMgYW5kIGNhdGVnb3JpY2FsIHZhcmlhYmxlcyB2aWEgYm94IHBsb3RzIHRvIGlsbHVzdHJhdGUgaG93IGRpc3RyaWJ1dGlvbnMgb2YgQk1JIHZhcnkgYWNyb3NzIGRpYWJldGVzIGdyb3Vwcy4gV2UgYWxzbyBsb29rZWQgYXQgaGlnaCBkaW1lbnNpb25hbCByZWxhdGlvbnMgdXNpbmcgZmFjZXRlZCBhbmQgaW50ZXJhY3RpdmUgcGxvdHMuIFRvZ2V0aGVyLCB0aGVzZSBwcm92aWRlZCBwcmVsaW1pbmFyeSBpbnNpZ2h0cyBpbnRvIHRoZSBwYXR0ZXJucyBvZiByZWxhdGlvbnNoaXBzIHRoYXQgZXhpc3QgaW4gdGhlIGRhdGFzZXQgYW5kIGhlbHAgZXhwbGFpbiBmYWN0b3JzIGFzc29jaWF0ZWQgd2l0aCBkaWFiZXRlcyBmb3IgZnVydGhlciBhbmFseXNpcy4gIAoKClwKCiMjIDIuIEludHJvZHVjdGlvbgogIEluIHRoZSBVU0EsIGRpYWJldGVzIGltcGFjdHMgb3ZlciAzNyBtaWxsaW9uIEFtZXJpY2FucyBhbmQgMSBpbiA1IHBlb3BsZSB3aXRoIGRpYWJldGVzIGRvIG5vdCBrbm93IHRoZXkgaGF2ZSBpdCBhY2NvcmRpbmcgdG8gdGhlIENEQy4gT3ZlciAzOCUgb2YgdGhlIFVTIHBvcHVsYXRpb24gaGF2ZSBwcmUtZGlhYmV0ZXMgLSBhIGNvbmRpdGlvbiB0aGF0IGluY3JlYXNlcyB0aGUgcmlzayBvZiBkZXZlbG9waW5nIHR5cGUgMiBkaWFiZXRlcy4gSXQgaXMgb25lIG9mIHRoZSBtb3N0IHByZXZhbGVudCBjaHJvbmljIGRpc2Vhc2VzIGluIHRoZSBVUyA8YSAgIGhyZWY9Imh0dHBzOi8vd3d3LmNkYy5nb3YvcGNkL2lzc3Vlcy8yMDE5LzE5XzAxMDkuaHRtIiB0YXJnZXQ9Il9ibGFuayI+IFhpZSBldCBhbCAoMjAxOSk8L2E+IC4gVGhpcyBwcmVzZW50cyBhIHB1YmxpYyBoZWFsdGggaXNzdWUgdGhhdCBoYXMgZWNvbm9taWMgYnVyZGVucywgaW5jcmVhc2VkIG1vcnRhbGl0eSByYXRlcyBhbmQgb3RoZXIgaGVhbHRoIGNvbXBsaWNhdGlvbnMuIEl0IGlzIGVzdGltYXRlZCB0aGF0IHRoZSBlY29ub21pYyBidXJkZW4gb2YgZGlhYmV0ZXMgaW4gdGhlIFVTIGlzIGFib3V0ICQzMjcgYmlsbGlvbiBhbnVhbGx5IHdpdGggdGhlIGNvc3Qgb2YgY2FyZSBvbiB0aGUgcmlzZS4gV2l0aCBhIHJpc2UgaW4gdGhlIG51bWJlciBvZiBkaWFiZXRlcyBjYXNlcyBpbiByZWNlbnQgeWVhcnMgYW5kIGl0cyBlY29ub21pYyBidXJkZW4sIHVuZGVyc3RhbmRpbmcgb2YgcmlzayBmYWN0b3JzIGRyaXZpbmcgdGhlc2UgbnVtYmVycyBhcmUgZXNzZW50aWFsIHRvIGVuYWJsZSBwb2xpY2llcyB0aGF0IGludGVydmVuZSBvbiB0aGlzIG5hdGlvbmFsIGhlYWx0aCBjcmlzZXMuIFRyYWNraW5nIG9mIGNhc2VzIGJ5IHRoZSBCUkZTUyBpcyBvbmUgd2F5IHRoZSBVUyBpcyB1c2luZyB0byBjdXJiIGRpYWJldGVzIHByZXZhbGVuY2UgYW5kIGl0cyBhc3NvY2lhdGVkIHJpc2sgZmFjdG9ycyBhbmQgYWxzbyB0byBpbnRlcnZlbmUgb24gbW9kaWZpYWJsZSBsaWZlc3R5bGUgY2hvaWNlcy4gRm9yIG1vcmUgZGV0YWlscywgdmlzaXQgPGEgaHJlZj0iaHR0cHM6Ly93d3cuY2RjLmdvdi9kaWFiZXRlcy9hYm91dC9pbmRleC5odG1sP3V0bV9zb3VyY2U9Y2hhdGdwdC5jb20jY2RjX2Rpc2Vhc2VfYmFzaWNzX3F1aWNrX2ZhY3RzX2NhbGxvdXRfY2FsbG91dC1kaWFiZXRlcy1ieS10aGUtbnVtYmVycyIgdGFyZ2V0PSJfYmxhbmsiPkRpYWJldGVzIEJhc2ljczwvYT4gCgpUaGUgQmVoYXZpb3JhbCBSaXNrIEZhY3RvciBTdXJ2ZWlsbGFuY2UgU3lzdGVtIChCUkZTUykgaXMgYSB0ZWxlcGhvbmUgc3VydmV5IGNvbmR1Y3RlZCBhbm51YWxseSBieSB0aGUgQ2VudGVyIEZvciBEaXNlYXNlIENvbnRyb2wgYW5kIFByZXZlbnRpb24gKENEQykgdG8gY29sbGVjdCB1bmlmb3JtLCBzdGF0ZS1zcGVjaWZpYyBkYXRhIG9uIFVTIGFkdWx0cycgaGVhbHRoLXJlbGF0ZWQgcmlzayBiZWhhdmlvcnMsIGNocm9uaWMgaGVhbHRoIGNvbmRpdGlvbnMgbGlrZSBkaWFiZXRlcywgYW5kIHVzZSBvZiBwcmV2ZW50aXZlIHNlcnZpY2VzLiBUaGUgZm9jdXMgb2YgdGhlIHN1cnZleSBpcyB0byBjb2xsZWN0IGRhdGEgb24gZGVtb2dyYXBoaWNzIGFuZCBzb2NpYWwgZGV0ZXJtaW5hbnRzIG9mIGhlYWx0aCwgbWVudGFsIGhlYWx0aCBhbmQgd2VsbCBiZWluZywgaGVhbHRoIHJpc2sgYmVoYXZpb3JzLCBjaHJvbmljIGhlYWx0aCBjb25kaXRpb25zIGFuZCB1c2Ugb2YgcHJldmVudGl2ZSBzZXJ2aWNlcyBpbiB0aGUgVW5pdGVkIFN0YXRlcyBwb3B1bGF0aW9uLiBJdCBpcyBhbiBpbXBvcnRhbnQgc3lzdGVtIHRoYXQgaGVscHMgcHVibGljIGhlYWx0aCBwZXJzb25uZWwgdG8gZGVzaWduIHBvbGljaWVzIGFuZCBoZWFsdGggcHJvZ3JhbXMgdGhhdCBiZW5lZml0cyBzdGF0ZXMgYW5kIGxvY2FsIGFnZW5jaWVzLiBEYXRhIGZyb20gdGhlIHN5c3RlbSBhbmQgdGhlIGN1cnJlbnQgYW5hbHlzaXMgaXMgdXRpbGl6ZWQgaW4gdGhlIGlkZW50aWZpY2F0aW9uIG9mIHJpc2sgZmFjdG9ycyB0aGF0IGNvbnRyaWJ1dGUgdG8gY2hyb25pYyBkaXNlYXNlcyBhbmQgaGVhbHRoIGRpc3Bhcml0aWVzIGFtb25nIGRpZmZlcmVudCBwb3B1bGF0aW9ucywgZXRjLiBXZSB3aWxsIHBhcnRpY3VsYXJpdHksIGV4cGxvcmUgdGhlIGFiaWxpdHkgdG8gaWRlbnRpZnkgd2hpY2ggZmVhdHVyZSB2YXJpYWJsZXMgaW4gdGhlIGRhdGEgYXJlIGFzc29jaWF0ZWQgd2l0aCBkaWFiZXRlcyBlaXRoZXIgYWxvbmUgb3IgaW4gY29tYmluYXRpb24gd2l0aCBvdGhlciByaXNrIGZhY3RvcnMgYW5kIGFsc28gdXNlIGFkdmFuY2UgbWV0aG9kcyBpbiBtYWNoaW5lIGxlYXJuaW5nIHRvIGFjY3VyYXRlbHkgcHJlZGljdCB3aGljaCBpbmRpdmlkdWFscyBoYXZlIGRpYWJldGVzIGJhc2VkIG9uIHRoZSByaXNrIGZhY3RvcnMgcmVwb3J0ZWQgaW4gdGhlIGxpdGVyYXR1cmUuIAoKCiogKipEZXNjcmlwdGlvbiBvZiBEYXRhKioKCiAgV2Ugd2lsbCB1c2UgdGhlIDIwMTUgQlJGU1MgZGF0YSBpbiBvdXIgZXhwbG9yYXRvcnkgYW5hbHlzaXMgb2YgdGhlIGZlYXR1cmUgdmFyaWFibGVzIGluIHRoaXMgZGF0YXNldC4gVGhlIGRhdGFzZXQgY29udGFpbnMgY2xlYW4gZGF0YSBvcmlnaW5hdGluZyBmcm9tIHRoZSBvcmlnaW5hbCBkYXRhc2V0IHdoaWNoIGNvbnRhaW5lZCA0NDEsIDQ1NSBpbmRpdmlkdWFscyBhbmQgaGFzIDMzMCBmZWF0dXJlcy4gVGhlIGNsZWFuIHZlcnNpb24gY29udGFpbnMgMjUzLDY4MSBzdXJ2ZXkgcmVzcG9uc2VzIGZyb20gdGhlIENEQydzIEJSRlNTIDIwMTUuIEl0IGNvbnRhaW5zIDIxIGZlYXR1cmUgdmFyaWFibGVzIGFuZCBvYnRhaW5lZCBmcm9tIHRoZSBrYWdnbGUgd2Vic2l0ZSA8YSAgIGhyZWY9Imh0dHBzOi8vd3d3LmthZ2dsZS5jb20vZGF0YXNldHMvYWxleHRlYm91bC9kaWFiZXRlcy1oZWFsdGgtaW5kaWNhdG9ycy1kYXRhc2V0P3V0bV9zb3VyY2U9Y2hhdGdwdC5jb20mc2VsZWN0PWRpYWJldGVzX2IgICBpbmFyeV9oZWFsdGhfaW5kaWNhdG9yc19CUkZTUzIwMTUuY3N2IiB0YXJnZXQ9Il9ibGFuayI+RGlhYmV0ZXMgSGVhbHRoIEluZGljYXRvcnMgRGF0YXNldDwvYT4KCiogKipGZWF0dXJlIFZhcmlhYmxlcyoqCgogIFRoZSBjbGVhbiBkYXRhc2V0IChCUkZTUzIwMTUpIGNvbnRhaW5zIHRoZSBmb2xsb3dpbmcgZmVhdHVyZXMKICAgKiAqKlRhcmdldCBmZWF0dXJlOioqIGEgY2F0ZWdvcmljYWwgZmVhdHVyZSBpbmRpY2F0aW5nIGlmIGFuIGluZGl2aWR1YWwgaGFzIGRpYWJldGVzIG9yIG5vdCwgRGlhYmV0ZXNfYmluYXJ5ICgwID0gbm8gZGlhYmV0ZXMsIDEgPSBwcmVkaWFiZXRlcyBvciBkaWFiZXRlcykKICAgCiAgICogKipJbmRlcGVuZGVudCB2YXJpYWJsZXMqKgogICAgICsgSGlnaEJQOiBhIGNhdGVnb3JpY2FsIGZlYXR1cmUgKDAgPSBubyBoaWdoIEJQLCAxID0gaGlnaCBCUCkKICAgICArIEhpZ2hDaG9sOiBhIGNhdGVnb3JpY2FsIGZlYXR1cmUgdGhhdCBpbmRpY2F0ZXMgaWYgYW4gaW5kaXZpZHVhbCBoYXMgaGlnaCBjaG9sZXN0ZXJvbCAoMSA9IFllcywgMCA9IE5vKQogICAgICsgQ2hvbENoZWNrOiBhIGNhdGVnb3JpY2FsIGZlYXR1cmUgdGhhdCBpbmRpY2F0ZXMgaWYgYW4gaW5kaXZpZHVhbCBoYWQgdGhlaXIgY2hvbGVzdGVyb2wgY2hlY2tlZCBpbiB0aGUgcGFzdCBmaXZlIHllYXJzICgxID0gWWVzLCAwID0gTm8pCiAgICAgKyBCTUk6IEJvZHkgTWFzcyBJbmRleCxhIGNvbnRpbnVvdXMgbnVtZXJpY2FsIGZlYXR1cmUgYmFzZWQgb24gdGhlIG1lYXN1cmUgb2YgYm9keSBmYXQgYmFzZWQgb24gaGVpZ2h0IGFuZCB3ZWlnaHQKICAgICArIFNtb2tlcjogYSBjYXRlZ29yaWNhbCBmZWF0dXJlIHRoYXQgaW5kaWNhdGVzIGlmIGFuIGluZGl2aWR1YWwgaGFzIHNtb2tlZCBhdCBsZWFzdCAxMDAgY2lnYXJldHRlcyBpbiB0aGVpciBsaWZldGltZSAoMSA9IFllcywgMCA9IE5vKQogICAgICsgU3Ryb2tlOiBhIGNhdGVnb3JpY2FsIGZlYXR1cmUgdGhhdCBpbmRpY2F0ZXMgaWYgYW4gaW5kaXZpZHVhbCBoYXMgaGFkIGEgc3Ryb2tlICgxID0gWWVzLCAwID0gTm8pCiAgICAgKyBIZWFydERpc2Vhc2VvckF0dGFjazogYSBjYXRlZ29yaWNhbCBmZWF0dXJlIHRoYXQgaW5kaWNhdGVzIGlmIGFuIGluZGl2aWR1YWwgaGFzIGNvcm9uYXJ5IGhlYXJ0IGRpc2Vhc2Ugb3IgYSBoZWFydCBhdHRhY2sgKDEgPSBZZXMsIDAgPSBObykKICAgICArIFBoeXNBY3Rpdml0eTogYSBjYXRlZ29yaWNhbCBmZWF0dXJlIHRoYXQgaW5kaWNhdGVzIGlmIGFuIGluZGl2aWR1YWwgaGFzIGVuZ2FnZWQgaW4gcGh5c2ljYWwgYWN0aXZpdHkgaW4gdGhlIHBhc3QgMzAgZGF5cyAoMSA9IFllcywgMCA9IE5vKQogICAgICsgRnJ1aXRzOiBhIGNhdGVnb3JpY2FsIGZlYXR1cmUgdGhhdCBpbmRpY2F0ZXMgaWYgdGhlIGluZGl2aWR1YWwgY29uc3VtZXMgZnJ1aXRzIGF0IGxlYXN0IG9uY2UgcGVyIGRheSAoMSA9IFllcywgMCA9IE5vKQogICAgICsgVmVnZ2llczogYSBjYXRlZ29yaWNhbCBmZWF0dXJlIHRoYXQgaW5kaWNhdGVzIGlmIHRoZSBpbmRpdmlkdWFsIGNvbnN1bWVzIHZlZ2V0YWJsZXMgYXQgbGVhc3Qgb25jZSBwZXIgZGF5ICgxID0gWWVzLCAwID0gTm8pCiAgICAgKyBIdnlBbGNvaG9sQ29uc3VtcDogYSBjYXRlZ29yaWNhbCBmZWF0dXJlIHRoYXQgaW5kaWNhdGVzIGhlYXZ5IGFsY29ob2wgY29uc3VtcHRpb24gKDEgPSBZZXMsIDAgPSBObykKICAgICArIEFueUhlYWx0aGNhcmU6IGEgY2F0ZWdvcmljYWwgZmVhdHVyZSB0aGF0IGluZGljYXRlcyBpZiB0aGUgaW5kaXZpZHVhbCBoYXMgYW55IGtpbmQgb2YgaGVhbHRoIGNhcmUgY292ZXJhZ2UgKDEgPSBZZXMsIDAgPSBObykKICAgICArIE5vRG9jYmNDb3N0OiBhIGNhdGVnb3JpY2FsIGZlYXR1cmUgdGhhdCBpbmRpY2F0ZXMgaWYgdGhlIGluZGl2aWR1YWwgY291bGQgbm90IHNlZSBhIGRvY3RvciBkdWUgdG8gY29zdCBpbiB0aGUgcGFzdCAxMiBtb250aHMgKDEgPSBZZXMsIDAgPSBObykKICAgICArIEdlbkhsdGg6IGEgY2F0ZWdvcmljYWwgZmVhdHVyZSB0aGF0IGluZGljYXRlcyBHZW5lcmFsIGhlYWx0aCBzdGF0dXMgKDEgPSBFeGNlbGxlbnQsIDIgPSBWZXJ5IGdvb2QsIDMgPSBHb29kLCA0ID0gRmFpciwgNSA9IFBvb3IpCiAgICAgKyBNZW50SGx0aDogYSBudW1lcmljYWwgZmVhdHVyZSByZXByZXNlbnRpbmcgdGhlIG51bWJlciBvZiBkYXlzIG1lbnRhbCBoZWFsdGggd2FzIG5vdCBnb29kIGluIHRoZSBwYXN0IDMwIGRheXMKICAgICArIFBoeXNIbHRoOiBhIG51bWVyaWNhbCBudW1lcmljYWwgZmVhdHVyZSByZXByZXNlbnRpbmcgdGhlIG51bWJlciBvZiBkYXlzIHBoeXNpY2FsIGhlYWx0aCB3YXMgbm90IGdvb2QgaW4gdGhlIHBhc3QgMzAgZGF5cwogICAgICsgRGlmZldhbGs6IGEgY2F0ZWdvcmljYWwgaW5kaWNhdGVzIGlmIHRoZSBpbmRpdmlkdWFsIGhhcyBzZXJpb3VzIGRpZmZpY3VsdHkgd2Fsa2luZyBvciBjbGltYmluZyBzdGFpcnMgKDEgPSBZZXMsIDAgPSBObykKICAgICArIFNleDogYSBjYXRlZ29yaWNhbCBmZWF0dXJlIHRoYXQgaW5kaWNhdGVzIHRoZSBnZW5kZXIgb2YgYW4gaW5kaXZpZHVhbCAoMSA9IE1hbGUsIDAgPSBGZW1hbGUpCiAgICAgKyBBZ2U6IGEgY2F0ZWdvcmljYWwgZmVhdHVyZSByZXByZXNlbnRpbmcgdGhlIGFnZSBjYXRlZ29yeSBvZiB0aGUgaW5kaXZpZHVhbCAoMSA9IDE44oCTMjQsIDIgPSAyNeKAkzI5LCAzID0gMzDigJMzNCwgNCA9IDM14oCTMzksIDUgPSA0MOKAkzQ0LCA2ID0gNDXigJM0OSwgNyA9IDUw4oCTNTQsIDggPSA1NeKAkzU5LCA5ID0gICAgICAgICAgICA2MOKAkzY0LCAxMCA9IDY14oCTNjksIDExID0gNzDigJM3NCwgMTIgPSA3NeKAkzc5LCAxMyA9IDgwIG9yIG9sZGVyKQogICAgICsgRWR1Y2F0aW9uOiBhIGNhdGVnb3JpY2FsIHZhcmlhYmxlIHRoYXQgaW5kaWNhdGVzIEVkdWNhdGlvbiBsZXZlbCBvZiB0aGUgaW5kaXZpZHVhbCAoMSA9IE5ldmVyIGF0dGVuZGVkIHNjaG9vbCBvciBvbmx5IGtpbmRlcmdhcnRlbiwgMiA9IEdyYWRlcyAxIHRocm91Z2ggOCAoRWxlbWVudGFyeSksIDMgPSAgICAgICAgR3JhZGVzIDkgdGhyb3VnaCAxMSAoU29tZSBoaWdoIHNjaG9vbCwgbm8gZGlwbG9tYSksIDQgPSBHcmFkZSAxMiBvciBHRUQgKEhpZ2ggc2Nob29sIGdyYWR1YXRlKSwgNSA9IENvbGxlZ2UgMSB0byAzIHllYXJzIChTb21lIGNvbGxlZ2Ugb3IgdGVjaG5pY2FsIHNjaG9vbCksIDYgPSBDb2xsZWdlIDQgICAgICAgIHllYXJzIG9yIG1vcmUgKENvbGxlZ2UgZ3JhZHVhdGUpICkKICAgICArIEluY29tZTogYSBjYXRlZ29yaWNhbCB2YXJpYWJsZSB0aGF0IGluZGljYXRlcyBJbmNvbWUgY2F0ZWdvcnkgb2YgdGhlIGluZGl2aWR1YWwgKCAxID0gTGVzcyB0aGFuICQxMCwwMDAsIDIgPSAgJDEwLDAwMCB0byAkMTQsOTk5LCAzID0gJDE1LDAwMCB0byAkMTksOTk5LCA0ID0gJDIwLDAwMCB0byAgICAgICAgICAgJDI0LDk5OSwgNSA9ICQyNSwwMDAgdG8gJDM0LDk5OSwgNiA9ICQzNSwwMDAgdG8gJDQ5LDk5OSwgNyA9ICQ1MCwwMDAgdG8gJDc0LDk5OSwgOCA9ICQ3NSwwMDAgb3IgbW9yZSkKClwKCiMjIDMuIERpc3RyaWJ1dGlvbiBvZiBJbmRpdmlkdWFsIEZlYXR1cmVzCgpcClRvIHByZXBhcmUgdGhlIGRhdGFzZXQgZm9yIG91ciBhbmFseXNpcyBwdXJwb3NlLCB3ZSB1dGlsaXplZCB0aGUgc2FtcGxlIGZ1bmN0aW9uIHRvIGNyZWF0ZSBzb21lIG1pc3NpbmduZXNzIGluIG91ciBkYXRhc2V0LiBXZSByYW5kb21seSByZXBsYWNlZCA1JSBvZiBhbGwgZmVhdHVyZSB2YXJpYWJsZXMgd2l0aCBtaXNzaW5nIHZhbHVlcyB0byBtYWtlIHRoZSBkYXRhc2V0IHJlcHJlc2VudCByZWFsIHdvcmxkIGRhdGEgd2hpY2ggaXMgb2Z0ZW4gb2JzZXJ2ZWQgd2l0aCBtaXNzaW5nIHZhbHVlcyBpbiB2YXJpYWJsZXMuICBJdCBpcyBpbXBvcnRhbnQgdG8gcG9pbnQgb3V0IHRoYXQgc2luY2UgdGhpcyBpcyBhbiBhbHJlYWR5IGNsZWFuZWQgZGF0YXNldCwgdGhlcmUgYXJlIG5vdCBtdWNoIHRvIGJlIGRvbmUgaW4gYWRkcmVzc2luZyBpc3N1ZXMgbGlrZSB1bmxpa2VseSB2YWx1ZXMgKCBleHRyZW1lIGhlaWdodCBvciB3ZWlnaHQsIGV0Yywgbm9uIHN0YW5kYXJkIHJlc3BvbnNlIHRvIHF1ZXN0aW9ubmFpcmVzIGFtb25nIG90aGVycykuIFdlIHdpbGwgdXRpbGl6ZSBleHBsb3JhdG9yeSBkYXRhIGFuYWx5c2lzIHRvIHVuY292ZXIgcGF0dGVybnMgYW5kIHJlbGF0aW9uc2hpcHMgaW4gdGhlIGRhdGFzZXQuIEZlYXR1cmUgZW5naW5lZXJpbmcgd2lsbCBiZSBhcHBsaWVkIHdoZXJlIGFwcGxpY2FibGUgdG8gY3JlYXRlIG5ldyB2YXJpYWJsZXMgYW5kIGEgdmlzdWFsIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBkYXRhIHdpbGwgYmUgcHJvdmlkZWQgdG8gaWRlbnRpZnkgdHJlbmRzIGFuZCBmZWF0dXJlIHZhcmlhYmxlIGRpc3RyaWJ1dGlvbnMuIEFkZGl0aW9uYWxseSwgc3ViIGdyb3VwIHZpc3VhbGl6YXRpb25zIHdpbGwgYmUgcHJlc2VudGVkIHRoYXQgZW5saWdodGVucyBvdXIgdW5kZXJzdGFuZGluZyBvZiBob3cgZGlhYmV0ZXMgYWZmZWN0cyBjZXJ0YWluIGdyb3VwcyBvZiBwZW9wbGUgYW5kIHdoaWNoIGZlYXR1cmUgdmFyaWFibGVzIGFyZSBhc3NvY2lhdGVkIHdpdGggZGlhYmV0ZXMuIAoKKiAqKkluZGl2aWR1YWwgYW5hbHl0aWMgdGFza3MqKiAtClRoZSBmb2xsb3dpbmcgZmVhdHVyZSB2YXJpYWJsZXMgY29tcHJpc2Ugb2Ygc29tZSBvZiB0aGUgcmlzayBmYWN0b3JzIHRoYXQgYXJlIHJlcG9ydGVkIHRvIGJlIGFzc29jaWF0ZWQgd2l0aCBkaWFiZXRlcyB0aGF0IHdpbGwgYmUgc3R1ZGllZC4KICArIEJNSTogQk1JIGhpc3RvZ3JhbSBzaG93ZWQgcG9zaXRpdmVseSBza2V3ZWQgZGF0YSB3aGlsZSBhIGJveCBwbG90IGFsc28gc2hvd2VkIG91dGxpZXJzLiBUaGUgb3V0bGllcnMgd2VyZSByZW1vdmVkIGZyb20gdGhlIGRhdGFzZXQgdGhhdCB3ZXJlIDEuNSB0aW1lcyBsb3dlciBvciBoaWdoZXIgdGhhbiB0aGUgICAgIGZpcnN0IGFuZCB0aGlyZCBxdWFydGlsZXMuIFRoZSBwbG90IG9mIHRoZSBkYXRhIHdpdGhvdXQgdGhlIG91dGxpZXJzIHNob3dlZCBhIHNtb290aGVyIGRpc3RyaWJ1dGlvbi4KICAgIEJNSSB3YXMgcmUtY2F0ZWdvcml6ZWQgaW50byBVbmRlcndlaWdodCwgTm9ybWFsLCBPdmVyd2VpZ2h0IGFuZCBPYmVzZS4gT3ZlciA3MCUgb2YgdGhlIHNhbXBsZSB3ZXJlIGVpdGhlciBvdmVyd2VpZ2h0IG9yIG9iZXNlIHRvIGhlbHAgaWRlbnRpZnkgYXQgcmlzayBwb3B1bGF0aW9ucyBhbmQgZWFzaWVyIGludGVycHJldGF0aW9uIG9mIHRoZSBkYXRhIGFuZCBmb3IgdHJlbmQgaWRlbnRpZmljYXRpb24uIEl0IHdhcyBhcHBhcmVudCB0aGF0IG1vc3Qgb2YgdGhlIHBhcnRpY2lwYW50cyB3aGVyZSBlaXRoZXIgb3ZlciB3ZWlnaHQgb3Igb2Jlc2UuCgpgYGB7ciBjbGVhbmRhdGEsIHJlc3VsdHM9J2hpZGUnfQojIGdldCBkYXRhIGludG8gUgojc2V0d2QoIn4iKQojZ2V0d2QoKQoKbGlicmFyeShkcGx5cikKI2RkYXQgPC0gcmVhZC5jc3YoIi9Vc2Vycy9ta2F0dWFoZW5lL0Rlc2t0b3AvV0NVL1ItTWFjaGluZSBMZWFybmluZy9Bc3NpZ25tZW50L1dlZWsgMi9kaWFiZXRlc19iaW5hcnlfaGVhbHRoX2luZGljYXRvcnNfQlJGU1MyMDE1LmNzdiIsIHNraXA9MCkKZGRhdCA8LSByZWFkLmNzdigiaHR0cHM6Ly9tYXR1YWhlbmUuZ2l0aHViLmlvL1NUQTU1Mi9XZWVrJTIwMi9kaWFiZXRlc19iaW5hcnlfaGVhbHRoX2luZGljYXRvcnNfQlJGU1MyMDE1LmNzdiIsIHNraXA9MCkKCiNnZXR3ZCgpCiMgQ2F0ZWdvcml6ZSBpbmNvbWUgdmFyaWFibGUKZGRhdCRJbmNvbWVfY2F0IDwtIGN1dChkZGF0JEluY29tZSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrcyA9IGMoLUluZiwgMywgNSwgNiwgSW5mKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVscyA9IGMoIkxvdyIsICJNZWRpdW0iLCAiSGlnaCIsICJWZXJ5IEhpZ2giKSkKCiN0YWJsZShkZGF0JEluY29tZSAsIGRkYXQkSW5jb21lX2NhdCApCgpkZGF0MiA8LWRkYXQKI2NvbFN1bXMoaXMubmEoZGRhdDIpKQoKCiMgYXNzaWduIG1lYW5pbmdmdWwgbGFiZWxzIHRvIEFnZQpkZGF0MiRBZ2UgPC0gZmFjdG9yKGRkYXQyJEFnZSwgCiAgbGV2ZWxzID0gMToxMywgCiAgbGFiZWxzID0gYygiMTgtMjQgeXJzIiwgIjI1LTI5IHlycyIsICIzMC0zNCB5cnMiLCAiMzUtMzkgeXJzIiwgIjQwLTQ0IHlycyIsIAogICAgICAgICAgICAgIjQ1LTQ5IHlycyIsICI1MC01NCB5cnMiLCAiNTUtNTkgeXJzIiwgIjYwLTY0IHlycyIsICI2NS02OSB5cnMiLCAKICAgICAgICAgICAgICI3MC03NCB5cnMiLCAiNzUtNzkgeXJzIiwgIjgwKyB5cnMiKSkKCgoKIyBCTUkgY2F0ZWdvcmllcwpkZGF0MiA8LSBkZGF0MiAlPiUKICBtdXRhdGUoQk1JX0NhdCA9IGN1dChCTUksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWtzID0gYygwLCAxOC41LCAyNC45LCAyOS45LCBJbmYpLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVscyA9IGMoIlVuZGVyd2VpZ2h0IiwgIk5vcm1hbCIsICJPdmVyd2VpZ2h0IiwgIk9iZXNlIikpKQoKCgojIFlFUy9OTyBsYWJlbHMKZGRhdDIgPC0gZGRhdDIgJT4lCiAgbXV0YXRlKAogICAgSGlnaENob2wgPSByZWNvZGUoSGlnaENob2wsICIwIiA9ICJObyIsICIxIiA9ICJZZXMiKSwKICAgIEhpZ2hCUCA9IHJlY29kZShIaWdoQlAsICIwIiA9ICJObyIsICIxIiA9ICJZZXMiKSwKICAgIFNtb2tlciA9IHJlY29kZShTbW9rZXIsICIwIiA9ICJObyIsICIxIiA9ICJZZXMiKSwKICAgIFN0cm9rZSA9IHJlY29kZShTdHJva2UsICIwIiA9ICJObyIsICIxIiA9ICJZZXMiKSwKICAgIEhlYXJ0RGlzZWFzZW9yQXR0YWNrID0gcmVjb2RlKEhlYXJ0RGlzZWFzZW9yQXR0YWNrLCAiMCIgPSAiTm8iLCAiMSIgPSAiWWVzIiksCiAgICBQaHlzQWN0aXZpdHkgPSByZWNvZGUoUGh5c0FjdGl2aXR5LCAiMCIgPSAiTm8iLCAiMSIgPSAiWWVzIiksCiAgICBGcnVpdHMgPSByZWNvZGUoRnJ1aXRzLCAiMCIgPSAiTm8iLCAiMSIgPSAiWWVzIiksCiAgICBWZWdnaWVzID0gcmVjb2RlKFZlZ2dpZXMsICIwIiA9ICJObyIsICIxIiA9ICJZZXMiKQogICkKCgojRGlhYmV0ZXMgc3RhdHVzLCBFZHVjYXRpb24gYW5kIEluY29tZSwgZXRjIGxhYmVscwpkZGF0MiA8LSBkZGF0MiAlPiUKICBtdXRhdGUoCiAgICBFZHVjYXRpb24gPSByZWNvZGUoRWR1Y2F0aW9uLCAKICAgICAgICAgICAgICAgICAgICAgICAiMSIgPSAiTm8gSGlnaCBTY2hvb2wiLCAKICAgICAgICAgICAgICAgICAgICAgICAiMiIgPSAiU29tZSBIaWdoIFNjaG9vbCIsIAogICAgICAgICAgICAgICAgICAgICAgICIzIiA9ICJIaWdoIFNjaG9vbCBHcmFkdWF0ZSIsIAogICAgICAgICAgICAgICAgICAgICAgICI0IiA9ICJTb21lIENvbGxlZ2UiLCAKICAgICAgICAgICAgICAgICAgICAgICAiNSIgPSAiQ29sbGVnZSBHcmFkdWF0ZSIsCiAgICAgICAgICAgICAgICAgICAgICAgIjYiID0gIkNvbGxlZ2UgNCB5ZWFycyBvciBtb3JlIChDb2xsZWdlIGdyYWR1YXRlKSIpLAogICAgSW5jb21lID0gcmVjb2RlKEluY29tZSwgCiAgICAgICAgICAgICAgICAgICAgIjEiID0gIjwkMTBLIiwgCiAgICAgICAgICAgICAgICAgICAgIjIiID0gIiQxMEstJDE1SyIsIAogICAgICAgICAgICAgICAgICAgICIzIiA9ICIkMTVLLSQyNUsiLCAKICAgICAgICAgICAgICAgICAgICAiNCIgPSAiJDI1Sy0kMzVLIiwgCiAgICAgICAgICAgICAgICAgICAgIjUiID0gIiQzNUstJDUwSyIsIAogICAgICAgICAgICAgICAgICAgICI2IiA9ICIkNTBLLSQ3NUsiLCAKICAgICAgICAgICAgICAgICAgICAiNyIgPSAiPiQ3NUsiLAogICAgICAgICAgICAgICAgICAgIC5kZWZhdWx0ID0gIlVua25vd24iKSwKICAgU2V4ID0gcmVjb2RlKFNleCwgCiAgICAgICAgICAgICAgICAgICIxIiA9ICJNYWxlIiwgCiAgICAgICAgICAgICAgICAgICIwIiA9ICJGZW1hbGUiLAogICAgICAgICAgICAgICAgLmRlZmF1bHQgPSAiVW5rbm93biIpLAogICBDaG9sQ2hlY2sgPSByZWNvZGUoQ2hvbENoZWNrLAogICAgICAgICAgICAgICAgICAgICAgIjEiID0gIlllcyIsCiAgICAgICAgICAgICAgICAgICAgICAiMCIgPSAiTm8iICksCiAgIAogICBEaWZmV2FsayA9IHJlY29kZShEaWZmV2FsaywKICAgICAgICAgICAgICAgICAgICAgICIxIiA9ICJZZXMiLAogICAgICAgICAgICAgICAgICAgICAgIjAiID0gIk5vIiApLAogIAogICBBbnlIZWFsdGhjYXJlID0gcmVjb2RlKEFueUhlYWx0aGNhcmUsCiAgICAgICAgICAgICAgICAgICAgICAiMSIgPSAiWWVzIiwKICAgICAgICAgICAgICAgICAgICAgICIwIiA9ICJObyIgKSwKCiAgIE5vRG9jYmNDb3N0ID0gcmVjb2RlKE5vRG9jYmNDb3N0LAogICAgICAgICAgICAgICAgICAgICAgIjEiID0gIlllcyIsCiAgICAgICAgICAgICAgICAgICAgICAiMCIgPSAiTm8iICksCiAgSHZ5QWxjb2hvbENvbnN1bXAgPSByZWNvZGUoSHZ5QWxjb2hvbENvbnN1bXAsCiAgICAgICAgICAgICAgICAgICAgICAiMSIgPSAiWWVzIiwKICAgICAgICAgICAgICAgICAgICAgICIwIiA9ICJObyIgKSwKICAgIERpYWJldGVzX2JpbmFyeSA9IHJlY29kZShEaWFiZXRlc19iaW5hcnksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIjAiID0gIk5vIERpYWJldGVzIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAiMSIgPSAiSGFzIERpYWJldGVzIiksCiAgCiAgR2VuSGx0aCA9IHJlY29kZShHZW5IbHRoLAogICAgICAgICAgICAgICAgICAiMSIgPSAiRXhjZWxsZW50IiwKICAgICAgICAgICAgICAgICAgICIyIiA9ICJWZXJ5IEdvb2QiLAogICAgICAgICAgICAgICAgICAgIjMiID0gIkdvb2QiLAogICAgICAgICAgICAgICAgICAgIjQiID0gIkZhaXIiLAogICAgICAgICAgICAgICAgICAgIjUiID0gIlBvb3IiLAogICAgICAgICAgICAgICAgICAgLmRlZmF1bHQgPSAiVW5rbm93biIpCiAgKQoKCgojdGFibGUgKGRkYXQyJEluY29tZSkKI3VuaXF1ZShkZGF0MiRJbmNvbWUpCgojIGNyZWF0ZSBzb21lIG1pc3NpbmcgZGF0YSBwb2ludHMgCiMgRGVmaW5lIHRoZSBwZXJjZW50YWdlIG9mIG1pc3NpbmcgdmFsdWVzIAptaXNzaW5nX3BlcmNlbnRhZ2UgPC0gMC4wNQoKIyBHZXQgdG90YWwgbnVtYmVyIG9mIHJvd3MKdG90YWxfcm93cyA8LSBucm93KGRkYXQyKQoKIyBBcHBseSBtaXNzaW5nIHZhbHVlcyB0byBhbGwgdmFyaWFibGVzCmRkYXQyIDwtIGRkYXQyICU+JQogIG11dGF0ZShhY3Jvc3MoZXZlcnl0aGluZygpLCB+IHsKICAgIG1pc3NfaWQgPC0gc2FtcGxlKDE6dG90YWxfcm93cywgc2l6ZSA9IHJvdW5kKG1pc3NpbmdfcGVyY2VudGFnZSAqIHRvdGFsX3Jvd3MpLCByZXBsYWNlID0gRkFMU0UpCiAgICAuW21pc3NfaWRdIDwtIE5BICAjIEFzc2lnbiBOQSB0byBzZWxlY3RlZCByb3dzCiAgICAuCiAgfSkpCgoKCgojIG92ZXJhbGwgc3VtbWFyeSBvZiB2YXJpYWJsZXMKbGlicmFyeShzdW1tYXJ5dG9vbHMpCmRmU3VtbWFyeShkZGF0MikKCiN0YWJsZShkZGF0MiRBZ2UpCiN0YWJsZShkZGF0MiRCTUlfQ2F0KQojc3VtbWFyeSAoZGRhdDIkQk1JKQpgYGAKCgoKYGBge3IgQk1JLCByZXN1bHRzPSdoaWRlJ30KIyBnZXQgZGF0YSBpbnRvIFIKI0JNSSB2YXJpYWJsZQpsaWJyYXJ5KGdncGxvdDIpCmxpYnJhcnkoZ3JpZEV4dHJhKQpsaWJyYXJ5KGdyaWQpCmJtaTEgPC0gZ2dwbG90KGRkYXQyLCBhZXMoeCA9IEJNSSkpICsKICBnZW9tX2hpc3RvZ3JhbShiaW53aWR0aCA9IDIsIGZpbGwgPSAic3RlZWxibHVlIiwgY29sb3IgPSAiYmxhY2siLCBhbHBoYSA9IDAuNykgKwogIGxhYnModGl0bGUgPSAiQk1JIERpc3RyaWJ1dGlvbiIsIHggPSAiQk1JIiwgeSA9ICJDb3VudCIpICsKICB0aGVtZV9taW5pbWFsKCkKCmJtaTIgPC0gZ2dwbG90KGRkYXQyLCBhZXMoeCA9IEJNSSkpICsKICBnZW9tX2RlbnNpdHkoZmlsbCA9ICJsaWdodGJsdWUiLCBhbHBoYSA9IDAuNikgKwogIGxhYnModGl0bGUgPSAiRGVuc2l0eSBQbG90IG9mIEJNSSIsIHggPSAiQk1JIiwgeSA9ICJEZW5zaXR5IikgKwogIHRoZW1lX21pbmltYWwoKQoKYm1pMyA8LSBnZ3Bsb3QoZGRhdDIsIGFlcyh5ID0gQk1JKSkgKwogIGdlb21fYm94cGxvdChmaWxsID0gInRvbWF0byIsIGFscGhhID0gMC43LCBvdXRsaWVyLmNvbG9yID0gInJlZCIpICsKICBsYWJzKHRpdGxlID0gIkJveHBsb3Qgb2YgQk1JIiwgeSA9ICJCTUkiKSArCiAgdGhlbWVfbWluaW1hbCgpCgpncmlkLmFycmFuZ2UoYm1pMSwgYm1pMiwgYm1pMywgbmNvbCA9IDIsIHRvcCA9IHRleHRHcm9iKCJPdmVydmlldyBvZiBCTUkiLCBncCA9IGdwYXIoZm9udHNpemUgPSAxNiwgZm9udGZhY2UgPSAiYm9sZCIpKSkgCgojY2hlY2sgc2tld25lc3Mgb2YgQk1JCmxpYnJhcnkoZTEwNzEpCnNrZXduZXNzKGRkYXQyJEJNSSwgbmEucm09VFJVRSkgCnNrZXduZXNzKGRkYXQyJEJNSSwgbmEucm09VFJVRSkgCgojIHJlbW92ZSBCTUkgb3V0bGllcnMKUTEgPC0gcXVhbnRpbGUoZGRhdDIkQk1JLCAwLjI1LCBuYS5ybSA9IFRSVUUpClEzIDwtIHF1YW50aWxlKGRkYXQyJEJNSSwgMC43NSwgbmEucm0gPSBUUlVFKQpJUVIgPC0gUTMgLSBRMQoKIyBEZWZpbmUgYWNjZXB0YWJsZSByYW5nZQpsb3dlcl9ib3VuZCA8LSBRMSAtIDEuNSAqIElRUgp1cHBlcl9ib3VuZCA8LSBRMyArIDEuNSAqIElRUgoKIyBSZW1vdmUgb3V0bGllcnMKZGRhdDMgPC0gZGRhdDJbZGRhdDIkQk1JID49IGxvd2VyX2JvdW5kICYgZGRhdDIkQk1JIDw9IHVwcGVyX2JvdW5kLCBdCgoKCiNwbG90IG9mIEJNSSB3aXRoIG91dGxpZXJzIHJlbW92ZWQ6IGRkYXQzIG5vdyBjb250YWlucyBkYXRhIHdpdGggbm8gb3V0bGllcnMKYm1pMTIgPC0gZ2dwbG90KGRkYXQzLCBhZXMoeCA9IEJNSSkpICsKICBnZW9tX2hpc3RvZ3JhbShiaW53aWR0aCA9IDIsIGZpbGwgPSAic3RlZWxibHVlIiwgY29sb3IgPSAiYmxhY2siLCBhbHBoYSA9IDAuNykgKwogIGxhYnModGl0bGUgPSAiQk1JIERpc3RyaWJ1dGlvbiIsIHggPSAiQk1JIiwgeSA9ICJDb3VudCIpICsKICB0aGVtZV9taW5pbWFsKCkKCmJtaTIyIDwtIGdncGxvdChkZGF0MywgYWVzKHggPSBCTUkpKSArCiAgZ2VvbV9kZW5zaXR5KGZpbGwgPSAibGlnaHRibHVlIiwgYWxwaGEgPSAwLjYpICsKICBsYWJzKHRpdGxlID0gIkRlbnNpdHkgUGxvdCBvZiBCTUkiLCB4ID0gIkJNSSIsIHkgPSAiRGVuc2l0eSIpICsKICB0aGVtZV9taW5pbWFsKCkKCmJtaTMyIDwtIGdncGxvdChkZGF0MywgYWVzKHkgPSBCTUkpKSArCiAgZ2VvbV9ib3hwbG90KGZpbGwgPSAidG9tYXRvIiwgYWxwaGEgPSAwLjcsIG91dGxpZXIuY29sb3IgPSAicmVkIikgKwogIGxhYnModGl0bGUgPSAiQm94cGxvdCBvZiBCTUkiLCB5ID0gIkJNSSIpICsKICB0aGVtZV9taW5pbWFsKCkKCmdyaWQuYXJyYW5nZShibWkxMiwgYm1pMjIsIGJtaTMyLCBuY29sID0gMiwgdG9wID0gdGV4dEdyb2IoIk92ZXJ2aWV3IG9mIEJNSSB3aXRoIG5vIG91dGxpZXJzIiwgZ3AgPSBncGFyKGZvbnRzaXplID0gMTYsIGZvbnRmYWNlID0gImJvbGQiKSkpIAoKCiNjYXRlZ29yaXplZCBCTUkgYmFyIGNoYXJ0CmJtaWdycDwtIGdncGxvdChkZGF0MyAlPiUgZmlsdGVyKCFpcy5uYShCTUlfQ2F0KSksIGFlcyh4ID0gQk1JX0NhdCkpICsKICBnZW9tX2JhcihmaWxsID0gImxpZ2h0Ymx1ZSIgLCB3aWR0aCA9IDAuNikgKwogIGxhYnModGl0bGUgPSAiQk1JIENhdGVnb3JpZXMgRGlzdHJpYnV0aW9uIiwKICAgICAgIHggPSAiQk1JIGNhdGVnb3J5IiwKICAgICAgIHkgPSAiQ291bnQiCiAgICAgICApICsKICB0aGVtZV9jbGFzc2ljKCkgKwogIHRoZW1lKHBsb3QubWFyZ2luID0gbWFyZ2luKDIsIDIsIDIsIDIpICkKICAKYm1pZ3JwCmBgYAoKICArIERpYWJldGVzIFN0YXR1czogSW4gdGhlIHNhbXBsZSwgbWFqb3JpdHkgb2YgdGhlIHBhcnRpY2lwYW50cyBkaWQgbm90IGhhdmUgZGlhYmV0ZXMoODYlKS4gT25seSBhIHNtYWxsZXIgcHJvcG9ydGlvbiB3aGVyZSBkaWFiZXRpYyBvciBoYWQgcHJlLWRpYWJldGVzLiBUaGlzIHN1Z2dlc3RzIGxvdyBwcmV2YWxlbmNlIG9mIGRpYWJldGVzIGluIG91ciBzYW1wbGUuIAogICsgTWVudGFsIEhlYWx0aDogSGlzdG9ncmFtIGFuZCBkZW5zaXR5IHBsb3RzIHNob3dlZCBmZXcgcGVvcGxlIGhhZCBmZXcgZGF5cyB3aXRoIHBvb3IgbWVudGFsIGhlYWx0aCB0aGUgbGFzdCAzMCBkYXlzIChtZWFuID0gYXBwcm94aW1hdGVseSAzIGRheXMgb2YgYmFkIG1lbnRhbCBoZWFsdGggZGF5cykuCiAgICBPdXRsaWVycyB3ZXJlIHJlcGxhY2VkIHdpdGggbWVhbiB2YWx1ZXMuCiAgKyBQaHlzaWNhbCBIZWFsdGggaW4gbGFzdCAzMCBkYXlzIGRpc3RyaWJ1dGlvbiBzaG93ZWQgb3V0bGllcnMgYW5kIHRoZXNlIHZhbHVlcyB3ZXJlIHJlcGxhY2VkIHdpdGggdGhlIG1lYW4uCiAgKyBHZW5lcmFsIEhlYWx0aCBTdGF0dXM6IE1vc3QgcGVvcGxlIHJlcG9ydGVkIHZlcnkgZ29vZCBvciBnb29kIGhlYWx0aCBzdGF0dXMgb3ZlcmFsbCB3aXRoIHNrZXduZXNzIG9ic2VydmVkIHRvd2FyZHMgcG9vciBoZWFsdGguIAogICAgYW5kIHNvIG5vIHNwZWNpYWwgY2hhbmdlcyB3aWxsIGJlIGFwcGxpZWQgdG8gdGhlIHZhcmlhYmxlLiAKICArIEluY29tZSB2YXJpYWJsZSB3YXMgbmVnYXRpdmVseSBza2V3ZWQuIE1vc3QgcGFydGljaXBhbnRzIGVhcm5lZCBoaWdoZXIgaW5jb21lLiBUaGUgdmFyaWFibGUgaXMgY2F0ZWdvcml6ZWQgaW50byBMb3csIE1lZGl1bSwgYW5kIEhpZ2ggaW5jb21lIGxldmVscy4KICArIFNleDogTW9yZSBmZW1hbGVzIHBhcnRpY2lwYXRlZCBpbiB0aGUgc2FtcGxlIGRhdGEgdGhhbiBtYWxlcy4gCiAgKyBBZ2U6IERpc3RyaWJ1dGlvbiBvZiBhZ2Ugd2FzIHN1Y2ggdGhhdCBtYWpvcml0eSBvZiBwYXJ0aWNpcGFudHMgd2VyZSBiZXlvbmQgNDAgeWVhcnMgb2xkLiBUaGlzIHN1Z2dlc3RzIHRoYXQgbW9zdCBwYXJ0aWNpcGFudHMgd2VyZSBvbGRlciBhbmQgYWdlIHNob3VsZCAgICAgY29udHJvbGxlZCBmb3IgaW4gYW55IGFuYWx5c2lzLgogICsgRWR1Y2F0aW9uOiBNb3N0IG9mIHRoZSBwYXJ0aWNpcGFudHMgaGFkIGEgaGlnaCBzY2hvb2wgZGlwbG9tYSBvciBoaWdoZXIgKG92ZXIgODAlKS4gCiAgKyBIaWdoIGJsb29kIFByZXNzdXJlIGFuZCBIaWdoIENob2xlc3Rlcm9sOiBNb3JlIHBhcnRpY2lwYW50cyBkaWQgbm90IGhhdmUgaGlnaCBibG9vZCBwcmVzc3VyZSBhbmQgbW9yZSBkaWQgbm90IGhhdmUgYW55IGNob2xlc3Rlcm9sIGNoZWNrcyBpbiB0aGUgbGFzdCA1IHllYXJzLiAKICArIFNtb2tlcjogQWJvdXQgNDQlIG9mIHRoZSBwYXJ0aWNpcGFudHMgc21va2VkIGF0IGxlYXN0IDEwMCBjaWdhcmV0dGVzIGluIHRoZWlyIGVudGlyZSBsaWZldGltZS4gQ29uc2lkZXJpbmcgaG93IHNtb2tpbmcgYWZmZWN0cyBvdXIgaGVhbHRoIGFuZCB3aXRoIHN1Y2ggbWFueSBpbiAgICAgc2FtcGxlLCBjb250cm9sbGluZyBmb3IgdGhpcyB2YXJpYWJsZSBpbiBvdXIgYW5hbHlzaXMgYW5kIGV4cGxvcmluZyBob3cgdGhpcyB2YXJpYWJsZSBpbnRlcmFjdHMgd2l0aCBvdGhlcnMgdG8gaW1wYWN0IGRpYWJldGVzIHdpbGwgYmUgc3R1ZGllZC4KICArIEhlYXZ5IEFsY29ob2wgY29uc3VtcHRpb24gLSBib3RoIG1lbiBhbmQgd29tZW4gcmVwb3J0ZWQgdGhleSBhcmUgbm90IGhlYXZ5IGRyaW5rZXJzIGJ1dCB0aGVzZSBjb3VsZCBiZSBpbmNvcnJlY3QgcmVwcmVzZW50YXRpb24gZHVlIHRvIHRoZSBmYWN0IHRoYXQgdGhleSBtYXkgcmVwb3J0IGFzIG5vdCBoZWF2eSBkcmlua2VycyBmb3Igc29jaWFsbHkgZGVzaXJhYmxlIHJlc3BvbnNlcyBhbmQgZXhwZWN0YXRpb25zLiBUaGUgYW5hbHlzaXMgY2FuIGJlIGNvbmR1Y3RlZCBmb3IgbWVuIGFuZCB3b21lbiBzZXBhcmF0ZWx5IGFuZCBmb3IgdGhvc2Ugd2hvIHJlcG9ydGVkIGFzIGhlYXZ5IGRyaW5rZXJzIHRvIHVuY292ZXIgaGlkZGVuIHJlbGF0aW9ucy4gCiAgKyBIZWFydCBkaXNlYXNlL2F0dGFjayB3YXMgbm90IHByZXZhbGVudCBpbiBvdXIgc2FtcGxlLiBCdXQgd2Uga25vdyB0aGF0IGRpYWJldGVzIGltcGFjdHMgdGhlIGhlYXJ0IGZ1bmN0aW9uLCBpdCB3aWxsIGJlIGludGVyZXN0aW5nIHRvIHNlZSBpZiB0aG9zZSB3aG8gaGFkIGRpYWJldGVzIHJlcG9ydGVkIHRvIGF2ZSBoYWQgYW55IG9mIHRoZXNlIGNvbmRpdGlvbnMuIAogICsgU3Ryb2tlOiBNb3N0IHBlb3BsZSBoYWQgbmV2ZXIgYmVlbiB0b2xkIHRoZXkgaGFkIGRpYWJldGVzICg5NSUpLiAKICArIE90aGVyIHZhcmlhYmxlczogTW9zdCBwZW9wbGUgZGlkIG5vdCBoYXZlIGRpZmZpY3VsdHkgd2Fsa2luZyB1cCB0aGUgc3RhaXJzLCB3ZXJlIHBoeXNpY2FsbHkgYWN0aXZlIGluIHRoZSBwYXN0IDMwIGRheXMsIGhhZCBzb21lIGZvcm0gb2YgaGVhbHRoIGluc3VyYW5jZSBhbmQgY291bGQgc2VlIGEgZG9jdG9yIHdoZW4gbmVlZGVkLCBjb25zdW1lZCB2ZWdldGFibGVzIG9uY2Ugb3IgbW9yZSB0aW1lcyBhIGRheSwgYnV0IHNsaWdodGx5IG1vcmUgZGlkIG5vdCBjb25zdW1lIGZydWl0cyBhdCB0aGUgc2FtZSByYXRlIGFzIHZlZ2V0YWJsZXMuCgpgYGB7ciBNZW5ILCByZXN1bHRzPSdoaWRlJ30KIyBEaWFiZXRlcyBTdGF0dXMKZ2dwbG90KGRkYXQzICU+JSBmaWx0ZXIoIWlzLm5hKERpYWJldGVzX2JpbmFyeSkpLCBhZXMoeCA9IGZhY3RvcihEaWFiZXRlc19iaW5hcnkpKSkgKwogIGdlb21fYmFyKGZpbGwgPSAibGlnaHRibHVlIiAsIHdpZHRoID0gMC40KSArCiAgbGFicyh0aXRsZSA9ICJEaWFiZXRlcyBTdGF0dXMiLAogICAgICAgeCA9ICJEaWFiZXRlcyBTdGF0dXMiLAogICAgICAgeSA9ICJDb3VudCIKICAgICAgICkgKwogIHRoZW1lX2NsYXNzaWMoKSsKICB0aGVtZShwbG90Lm1hcmdpbiA9IG1hcmdpbigyLCAyLCAyLCAyKSApCgojUGVyY2VudGFnZXMgd2l0aGluIGRpYWJldGVzCkRpYWIucGVyY2VudGFnZXMgPC0gZGRhdDMgJT4lCiAgY291bnQoRGlhYmV0ZXNfYmluYXJ5KSAlPiUKICBtdXRhdGUoUGVyY2VudGFnZSA9IG4gLyBzdW0obikgKiAxMDApCkRpYWIucGVyY2VudGFnZXMKCiNNZW50YWwgSGVhbHRoIFZhcmlhYmxlcwpzdW1tYXJ5KGRkYXQzJE1lbnRIbHRoKQptZW5oMSA8LSBnZ3Bsb3QoZGRhdDIsIGFlcyh4ID0gTWVudEhsdGgpKSArCiAgZ2VvbV9kZW5zaXR5KGZpbGwgPSAieWVsbG93IiwgYWxwaGEgPSAwLjYpICsKICBsYWJzKHRpdGxlID0gIkRlbnNpdHkgUGxvdCBvZiBub3QgZ29vZCBtZW50YWwgaGVhbHRoIGRheXMiLCB4ID0gIk1lbnRhbCBIZWFsdGgiLCB5ID0gIkRlbnNpdHkiKSArCiAgdGhlbWVfbWluaW1hbCgpCgoKbWVuaDIgIDwtIGdncGxvdChkZGF0MywgYWVzKHggPSBNZW50SGx0aCkpICsKICBnZW9tX2hpc3RvZ3JhbShiaW53aWR0aCA9IDIsIGZpbGwgPSAieWVsbG93IiwgY29sb3IgPSAiYmxhY2siLCBhbHBoYSA9IDAuNykgKwogIGxhYnModGl0bGUgPSAiSGlzdG9ncmFtIG9mIG5vdCBnb29kIG1lbnRhbCBoZWFsdGggZGF5cyIsIHggPSAiRGF5cyIsIHkgPSAiQ291bnQiKSArCiAgdGhlbWVfbWluaW1hbCgpCgoKbWVuaDMgPC0gZ2dwbG90KGRkYXQzLCBhZXMoeSA9IE1lbnRIbHRoKSkgKwogIGdlb21fYm94cGxvdChmaWxsID0gInllbGxvdyIsIGFscGhhID0gMC43LCBvdXRsaWVyLmNvbG9yID0gInJlZCIpICsKICBsYWJzKHRpdGxlID0gIkJveHBsb3Qgb2YgTnVtYmVyIG9mIGRheXMgTWVudGFsIGhlYWx0aCB3YXMgbm90IGdvb2QiLCB5ID0gIk1lbnRhbCBIZWFsdGggRGF5cyIpICsKICB0aGVtZV9taW5pbWFsKCkKCgpncmlkLmFycmFuZ2UobWVuaDEsIG1lbmgyLCBtZW5oMywgbmNvbCA9IDIsIHRvcCA9IHRleHRHcm9iKCJPdmVydmlldyBvZiBNZW50YWwgSGVhbHRoIGluIFBhc3QgMzAgRGF5cyIsIGdwID0gZ3Bhcihmb250c2l6ZSA9IDE2LCBmb250ZmFjZSA9ICJib2xkIikpKSAKCiMgRGVmaW5lIGEgZnVuY3Rpb24gdG8gcmVwbGFjZSBvdXRsaWVycyB3aXRoIHRoZSBtZWFuCnJlcGxhY2Vfb3V0bGllcnNfd2l0aF9tZWFuIDwtIGZ1bmN0aW9uKHgpIHsKICBRMSA8LSBxdWFudGlsZSh4LCAwLjI1LCBuYS5ybSA9IFRSVUUpCiAgUTMgPC0gcXVhbnRpbGUoeCwgMC43NSwgbmEucm0gPSBUUlVFKQogIElRUiA8LSBRMyAtIFExCiAgCiAgIyBEZWZpbmUgbG93ZXIgYW5kIHVwcGVyIGJvdW5kcwogIGxvd2VyX2JvdW5kIDwtIFExIC0gMS41ICogSVFSCiAgdXBwZXJfYm91bmQgPC0gUTMgKyAxLjUgKiBJUVIKICAKICAjIFJlcGxhY2Ugb3V0bGllcnMgd2l0aCB0aGUgbWVhbgogIHhbeCA8IGxvd2VyX2JvdW5kIHwgeCA+IHVwcGVyX2JvdW5kXSA8LSBtZWFuKHgsIG5hLnJtID0gVFJVRSkKICAKICByZXR1cm4oeCkKfQoKIyBBcHBseSB0aGUgZnVuY3Rpb24gdG8gbWVudGFsIGhlYWx0aCB0byByZXBsYWNlIG91dGxpZXJzIHdpdGggbWVhbiB2YWx1ZQpkZGF0MyRNZW50SGx0aCA8LSByZXBsYWNlX291dGxpZXJzX3dpdGhfbWVhbihkZGF0MyRNZW50SGx0aCkKCiNQaHlzaWNhbCBIZWFsdGggaGlzdG9ncmFtClBoICA8LSBnZ3Bsb3QoZGRhdDMsIGFlcyh4ID0gUGh5c0hsdGgpKSArCiAgZ2VvbV9oaXN0b2dyYW0oYmlud2lkdGggPSAyLCBmaWxsID0gInN0ZWVsYmx1ZSIsIGNvbG9yID0gImJsYWNrIiwgYWxwaGEgPSAwLjcpICsKICBsYWJzKHRpdGxlID0gIlBoeXNpY2FsIEhlYWx0aCBEYXlzIiwgeCA9ICJEYXlzIiwgeSA9ICJDb3VudCIpICsKICB0aGVtZV9taW5pbWFsKCkKI1BoCgojIEFwcGx5IHRoZSBmdW5jdGlvbiB0byBtZW50YWwgaGVhbHRoIHRvIHJlcGxhY2Ugb3V0bGllcnMgd2l0aCBtZWFuIHZhbHVlCmRkYXQzJFBoeXNIbHRoIDwtIHJlcGxhY2Vfb3V0bGllcnNfd2l0aF9tZWFuKGRkYXQzJFBoeXNIbHRoKQoKI2NhdGVnb3JpemVkIEdlbmVyYWwgSGVhbHRoIGJhciBjaGFydApkZGF0MyA8LSBkZGF0MyAlPiUKICBtdXRhdGUoR2VuSGx0aCA9IGZhY3RvcihHZW5IbHRoLCAKICAgICAgICAgICAgICAgICAgICAgICAgICBsZXZlbHMgPSBjKCJQb29yIiwgIkZhaXIiLCAiR29vZCIsICJWZXJ5IEdvb2QiLCAiRXhjZWxsZW50IiksIAogICAgICAgICAgICAgICAgICAgICAgICAgIG9yZGVyZWQgPSBUUlVFKSkgIApHaCA8LSBnZ3Bsb3QoZGRhdDMgJT4lIGZpbHRlcighaXMubmEoR2VuSGx0aCkpLCBhZXMoeCA9IEdlbkhsdGgpKSArCiAgZ2VvbV9iYXIoZmlsbCA9ICJibHVlIiwgd2lkdGggPTAuNCkgKwogIGxhYnModGl0bGUgPSAiR2VuZXJhbCBIZWFsdGggU3RhdHVzIiwKICAgICAgIHggPSAiR2VuZXJhbCBIZWFsdGgiLAogICAgICAgeSA9ICJDb3VudCIKICAgICAgICkgKwogIHNjYWxlX3hfZGlzY3JldGUoZXhwYW5kID0gYygwLjEsIDAuMSkpKwogIHRoZW1lX2NsYXNzaWMoKQpHaAoKCiNjYXRlZ29yaXplZCBTZXggY2hhcnQKU2V4IDwtIGdncGxvdChkZGF0MyAlPiUgZmlsdGVyKCFpcy5uYShTZXgpKSwgYWVzKHggPSBTZXgpKSArCiAgZ2VvbV9iYXIoZmlsbCA9ICJibHVlIikgKwogIGxhYnModGl0bGUgPSAiR2VuZGVyIiwKICAgICAgIHggPSAiR2VuZGVyIiwKICAgICAgIHkgPSAiQ291bnQiCiAgICAgICApICsKICB0aGVtZV9jbGFzc2ljKCkKI1NleAp1bmlxdWUoZGRhdDMkU2V4KTsKCiMgQWdlIEdyb3VwcwpBZ2UgPC0gZ2dwbG90KGRkYXQyICU+JSBmaWx0ZXIoIWlzLm5hKEFnZSkpLCBhZXMoeCA9IEFnZSkpICsKICBnZW9tX2JhcihmaWxsID0gImJsdWUiKSArCiAgbGFicyh0aXRsZSA9ICJBZ2UgZ3JvdXAgQmFyIENoYXJ0IiwKICAgICAgIHggPSAiQWdlIEdyb3VwIiwKICAgICAgIHkgPSAiQ291bnQiCiAgICAgICApICsKICB0aGVtZV9jbGFzc2ljKCkKI0FnZQoKQWdlLnBlcmNlbnRhZ2VzIDwtIGRkYXQgJT4lCiAgY291bnQoQWdlKSAlPiUKICBtdXRhdGUoUGVyY2VudGFnZSA9IG4gLyBzdW0obikgKiAxMDApCkFnZS5wZXJjZW50YWdlcwoKIyBFZHVjYXRpb24KRWR1LnBlcmNlbnRhZ2VzIDwtIGRkYXQgJT4lCiAgY291bnQoRWR1Y2F0aW9uKSAlPiUKICBtdXRhdGUoUGVyY2VudGFnZSA9IG4gLyBzdW0obikgKiAxMDApCkVkdS5wZXJjZW50YWdlcwoKIyBTbW9rZXIKU21va2UucGVyY2VudGFnZXMgPC0gZGRhdCAlPiUKICBjb3VudChTbW9rZXIpICU+JQogIG11dGF0ZShQZXJjZW50YWdlID0gbiAvIHN1bShuKSAqIDEwMCkKU21va2UucGVyY2VudGFnZXMKCiMgU3Ryb2tlClN0cm9rZS5wZXJjZW50YWdlcyA8LSBkZGF0ICU+JQogIGNvdW50KFN0cm9rZSkgJT4lCiAgbXV0YXRlKFBlcmNlbnRhZ2UgPSBuIC8gc3VtKG4pICogMTAwKQpTdHJva2UucGVyY2VudGFnZXMKCmBgYAoKClwKCiMjIDQuIFJlbGF0aW9uc2hpcCBiZXR3ZWVuIEZlYXR1cmVzIC0gQml2YXJpYXRlCgpcCldlIHdpbGwgbm93IGV4cGxvcmUgYW5kIGhhdmUgdmlzdWFsaXphdGlvbnMgb2YgcmVsYXRpb25zaGlwcyBhbW9uZyBzZXZlcmFsIHZhcmlhYmxlcyBpbiBvdXIgc2FtcGxlIGRhdGEuIFdlIHdpbGwgYmUgbG9va2luZyBhdCB2aXN1YWxzIGZvciB0d28gb3IgbW9yZSBudW1lcmljYWwgZmVhdHVyZSB2YXJpYWJsZXMsIGNhdGVnb3JpY2FsIHZhcmlhYmxlcyBhbmQgdmlzdWFscyB0aGF0IGxvb2sgY29tYmluYXRpb25zIG9mIHRoZXNlIHRvIGFpZCBpbiBvdXIgdW5kZXJzdGFuZGluZyBvZiB0aGUgZGF0YSBhbmQgaG93IGl0IGluZmx1ZW5jZXMgb3VyIHVuZGVyc3RhbmRpbmcgb2YgaG93IHRvIGFwcHJvYWNoIGFuYWx5c2lzIG9mIHRoZSBkYXRhLiAKCiAgKyBEaWFiZXRlcyBhbmQgQk1JIHBsb3RzIDogVGhlIGJveCBwbG90IHNob3dpbmcgdGhlIGRpYWJldGVzIGFuZCBCTUkgcGxvdCBzaG93cyB0aGUgbWVkaWFuIEJNSSBpbiB0aGUgZGlhYmV0aWMgZ3JvdXAgaXMgaGlnaGVyIHN1Z2dlc3RzIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIAogICAgdGhlc2UgMiB2YXJpYWJsZXMuIEFkZGl0aW9uYWxseSwgdGhlIGRlbnNpdHkgcGxvdCBzaG93cyBoaWdoZXIgQk1JIGluIHRoZSBkaWFiZXRpYyBncm91cCB0aGFuIHRoZSBub24tZGlhYmV0aWMgZ3JvdXAuCiAgKyBEaWFiZXRlcyBhbmQgUGh5c2ljYWwgQWN0aXZpdHkgcGxvdDogVGhlIGJpdmFyaWF0ZSBwbG90IHNob3dzIHRoYXQgd2hpbGUgdGhlIGRpc3RyaWJ1dGlvbiBvZiBwaHlzaWNhbCBhY3Rpdml0eSBpbiB0aGUgcGFzdCAzMCBkYXlzIGlzIHNpbWlsYXIsIGZhciBsZXNzICAgICAgICAKICAgIGRpYWJldGljIHBlb3BsZSB3ZXJlIHBoeXNpY2FsbHkgYWN0aXZlIGluIHRoZSBsYXN0IDMwIGRheXMuCgoKCgpgYGB7ciB0d292YXIsIHJlc3VsdHM9J2hpZGUnfQojIyMjIyMjIyMjIHR3byB2YXJpYWJsZSByZWxhdGlvbnNoaXBzCgojIGRpYWJldGVzIGFuZCBCTUkKIApnZ3Bsb3QoZGRhdDMlPiUgZmlsdGVyKCFpcy5uYShEaWFiZXRlc19iaW5hcnkpKSwgYWVzKHggPSBmYWN0b3IoRGlhYmV0ZXNfYmluYXJ5KSwgeSA9IEJNSSwgZmlsbCA9IGZhY3RvcihEaWFiZXRlc19iaW5hcnkpKSkgKwogIGdlb21fYm94cGxvdCgpICsKICBsYWJzKHRpdGxlID0gIkJNSSBEaXN0cmlidXRpb24gYnkgRGlhYmV0ZXMgU3RhdHVzIiwKICAgICAgIHggPSAiRGlhYmV0ZXMgU3RhdHVzIiwKICAgICAgIHkgPSAiQk1JIikgKwogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGMoInJlZCIsICJncmVlbiIpKSArCiAgdGhlbWVfY2xhc3NpYygpKwogIHRoZW1lKGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSkKCmdncGxvdChkZGF0MyU+JSBmaWx0ZXIoIWlzLm5hKERpYWJldGVzX2JpbmFyeSkpLCBhZXMoeCA9IEJNSSwgZmlsbCA9IGZhY3RvcihEaWFiZXRlc19iaW5hcnkpKSkgKwogIGdlb21fZGVuc2l0eShhbHBoYSA9IDAuNSkgKwogIGxhYnModGl0bGUgPSAiQk1JIERlbnNpdHkgUGxvdCBieSBEaWFiZXRlcyBTdGF0dXMiLAogICAgICAgeCA9ICJCTUkiLAogICAgICAgeSA9ICJEZW5zaXR5IikgKwogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGMoInJlZCIsICJncmVlbiIpKSArCiAgdGhlbWVfbWluaW1hbCgpKwogIHRoZW1lKGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSkKCgoKI2RpYWJldGVzIGFuZCBwaHlzaWNhbCBoZWFsdGgKCmdncGxvdChkZGF0MyU+JSBmaWx0ZXIoIWlzLm5hKERpYWJldGVzX2JpbmFyeSkgJiAhaXMubmEoUGh5c0FjdGl2aXR5KSksIGFlcyh4ID0gZmFjdG9yKERpYWJldGVzX2JpbmFyeSksIGZpbGwgPSBmYWN0b3IoUGh5c0FjdGl2aXR5KSkpICsKICBnZW9tX2Jhcihwb3NpdGlvbiA9ICJkb2RnZSIpICsKICBsYWJzKHRpdGxlID0gIkdyb3VwZWQgQmFyIFBsb3Qgb2YgRGlhYmV0ZXMgU3RhdHVzIGFuZCBQaHlzaWNhbCBBY3Rpdml0eSBpbiBwYXMgMzAgZGF5cyIsCiAgICAgICB4ID0gIkRpYWJldGVzIFN0YXR1cyIsCiAgICAgICB5ID0gIkNvdW50IikgKwogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGMoImJsdWUiLCAicmVkIiwgImdyZWVuIikpICsKICBndWlkZXMoZmlsbCA9IGd1aWRlX2xlZ2VuZCh0aXRsZSA9ICJQeXNpY2FsbHkgQWN0aXZlIGxhc3QgMzAgZGF5cyIpKSArCiAgdGhlbWVfY2xhc3NpYygpCiAgCgojY29sbmFtZXMoZGRhdDMpCgpgYGAKCgoKYGBge3IgbXVsdGl2YXJ9CiNjb3JyZWxhdGlvbiBwbG90IG9mIG51bWVyaWNhbCB2YXJpYWJsZXMKbGlicmFyeShnZ2NvcnJwbG90KQpzZWxlY3RfdmFycyA8LSBjKCJQaHlzSGx0aCIsICJNZW50SGx0aCIsICJHZW5IbHRoIiwgIkJNSSIpCmNvcnJfbWF0cml4IDwtIGNvcihkZGF0ICU+JSBzZWxlY3QoYWxsX29mKHNlbGVjdF92YXJzKSksIHVzZSA9ICJjb21wbGV0ZS5vYnMiKQoKbGlicmFyeShnZ3Bsb3QyKQpsaWJyYXJ5KHJlc2hhcGUyKQoKIyBDb252ZXJ0IG1hdHJpeCB0byBsb25nIGZvcm1hdApjb3JyX21lbHQgPC0gbWVsdChjb3JyX21hdHJpeCkKCiMgUGxvdCBoZWF0bWFwCiMgUGxvdCB3aXRoIHRleHQgbGFiZWxzCmNvcjEgPC0gZ2dwbG90KGNvcnJfbWVsdCwgYWVzKHggPSBWYXIxLCB5ID0gVmFyMiwgZmlsbCA9IHZhbHVlKSkgKwogIGdlb21fdGlsZSgpICsKICBnZW9tX3RleHQoYWVzKGxhYmVsID0gcm91bmQodmFsdWUsIDIpKSwgY29sb3IgPSAiYmxhY2siLCBzaXplID0gNCkgKyAgIyBBZGQgdmFsdWVzCiAgc2NhbGVfZmlsbF9ncmFkaWVudDIobG93ID0gImJsdWUiLCBtaWQgPSAid2hpdGUiLCBoaWdoID0gInJlZCIsIG1pZHBvaW50ID0gMCkgKwogIHRoZW1lX21pbmltYWwoKSArCiAgbGFicyh0aXRsZSA9ICJDb3JyZWxhdGlvbiBIZWF0bWFwIiwgZmlsbCA9ICJDb3JyZWxhdGlvbiIpICsKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCBoanVzdCA9IDEpKQoKI2luc3RhbGwucGFja2FnZXMoImNvcnJwbG90IikKbGlicmFyeShjb3JycGxvdCkKCmNvcnJwbG90KGNvcnJfbWF0cml4LCBtZXRob2QgPSAiY29sb3IiLCB0eXBlID0gInVwcGVyIiwKICAgICAgICAgY29sID0gY29sb3JSYW1wUGFsZXR0ZShjKCJibHVlIiwgIndoaXRlIiwgInJlZCIpKSgyMDApLAogICAgICAgICB0bC5jZXggPSAwLjcsIHRsLmNvbCA9ICJibGFjayIsCiAgICAgICAgIGFkZENvZWYuY29sID0gImJsYWNrIiwgbnVtYmVyLmNleCA9IDAuOCkgICMgQWRkIHZhbHVlcwoKCiNpbnN0YWxsLnBhY2thZ2VzKCJwbG90bHkiKQpsaWJyYXJ5KGdncGxvdDIpCmxpYnJhcnkocGxvdGx5KQp1bmlxdWUoZGRhdDMkSW5jb21lX2NhdCkKbXljb2xvcnMgPC0gYygiTG93IiA9ICJyZWQiLCAiTWVkaXVtIiA9ICJvcmFuZ2UiLCAiSGlnaCIgPSAiZ3JlZW4iLCAiVmVyeSBIaWdoIiA9ICJibHVlIikKCmdncGxvdGx5X2RlbnNpdHkgPC0gZGRhdDMlPiUgZmlsdGVyKCFpcy5uYShJbmNvbWVfY2F0KSAmICFpcy5uYShEaWFiZXRlc19iaW5hcnkpKSAgJT4lIAogIGdncGxvdChhZXMoeCA9IEJNSSwgY29sb3IgPSBJbmNvbWVfY2F0LCBmaWxsID0gSW5jb21lX2NhdCkpICsKICBnZW9tX2RlbnNpdHkobGluZXdpZHRoID0gMC43NSwgYWxwaGEgPSAwLjYpICsKICB4bGFiKCJCTUkgSW5kZXgiKSArIAogIGxhYnMoY29sb3IgPSAiSW5jb21lIEdyb3VwcyIsIGZpbGwgPSAiSW5jb21lIEdyb3VwcyIpICsKICBnZ3RpdGxlKCJEZW5zaXR5IEN1cnZlIG9mIEJNSSBhY3Jvc3MgSW5jb21lIEdyb3VwcyIpICsKICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gbXljb2xvcnMpICsgICMgQ3VzdG9tIGxpbmUgY29sb3JzCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gbXljb2xvcnMpICsgICMgQ3VzdG9tIGZpbGwgY29sb3JzCiAgICAgICAgICAgdGhlbWUocGxvdC5tYXJnaW4gPSB1bml0KGMoMiwxLDIsMSksICJjbSIpLAogICAgICAgICAgICAgICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSkpICArIAogIGZhY2V0X3dyYXAofiBEaWFiZXRlc19iaW5hcnkpICAjIFNwbGl0IGJ5IGRpYWJldGVzIHN0YXR1cwoKZ2dwbG90bHkoZ2dwbG90bHlfZGVuc2l0eSkKCgoKbXljb2xvcnMubiA8LSBjKCJQb29yIiA9ICJyZWQiLCAiRmFpciIgPSAib3JhbmdlIiwgIkdvb2QiID0gImdyZWVuIiwgIlZlcnkgR29vZCIgPSAiYmx1ZSIsICJFeGNlbGxlbnQiID0gImxpZ2h0Ymx1ZSIpCmdncGxvdGx5X2RlbnNpdHkubiA8LSBkZGF0MyU+JSBmaWx0ZXIoIWlzLm5hKEdlbkhsdGgpICYgIWlzLm5hKERpYWJldGVzX2JpbmFyeSkpICAlPiUgCiAgZ2dwbG90KGFlcyh4ID0gQk1JLCBjb2xvciA9IEdlbkhsdGgsIGZpbGwgPSBHZW5IbHRoKSkgKwogIGdlb21fZGVuc2l0eShsaW5ld2lkdGggPSAwLjc1LCBhbHBoYSA9IDAuNikgKwogIHhsYWIoIkJNSSBJbmRleCIpICsgCiAgbGFicyhjb2xvciA9ICJHZW5lcmFsIEhlYWx0aCIsIGZpbGwgPSAiR2VuZXJhbCBIZWFsdGgiKSArCiAgZ2d0aXRsZSgiRGVuc2l0eSBDdXJ2ZSBvZiBCTUkgYWNyb3NzIEdlbmVyYWwgSGVhbHRoIikgKwogIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBteWNvbG9ycy5uKSArICAjIEN1c3RvbSBsaW5lIGNvbG9ycwogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IG15Y29sb3JzLm4pICsgICMgQ3VzdG9tIGZpbGwgY29sb3JzCiAgICAgICAgICAgdGhlbWUocGxvdC5tYXJnaW4gPSB1bml0KGMoMiwxLDIsMSksICJjbSIpLAogICAgICAgICAgICAgICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSkpICArIAogIGZhY2V0X3dyYXAofiBEaWFiZXRlc19iaW5hcnkpICAjIFNwbGl0IGJ5IGRpYWJldGVzIHN0YXR1cwoKZ2dwbG90bHkoZ2dwbG90bHlfZGVuc2l0eS5uKQoKCgpgYGAKCgpcCgojIyA1LiBSZWxhdGlvbnNoaXAgYmV0d2VlbiBGZWF0dXJlcyAtIE11dGxpdmFyaWF0ZSAKClwKVGhlIGRlbnNpdHkgcGxvdCBvZiBCTUkgYW5kIEluY29tZSBncm91cHMgc2hvd3MgdGhhdCBCTUkgaXMgaGlnaGVzdCBpbiBtb3JlIHBhcnRpY2lwYW50cyBpbiB0aGUgbG93IGFuZCBtZWRpdW0gaW5jb21lIGdyb3Vwcy4gQW5kIHBhcnRpY2lwYW50cyBpbiB0aGUgdmVyeSBoaWdoIGluY29tZSBncm91cCBhcmUgYW1vbmcgdGhvc2Ugd2l0aCBCTUkgbGVzcyB0aGFuIDMwIG9yIGhlYWx0aGllci4gV2hlbiB0aGUgcGxvdCBpcyBzcGxpdCBieSBkaWFiZXRlcyBzdGF0dXMsIHdlIG9ic2VydmVkIHNpbWlsYXIgZGlzdHJpYnV0aW9uIGJ1dCB3ZSBzZWUgdGhhdCB2YXJpYW5jZSBpbiB0aGUgaW5jb21lIGdyb3VwcyBpcyBub3QgYXMgZGlzdGluY3QgZm9yIGhpZ2ggYW5kIHZlcnkgaGlnaCBncm91cHMuIFdoaWxlIGhpZ2hlciBCTUkgaXMgY29tb24gaW4gYWxsIGRpYWJldGljcywgaXQgaXMgbW9yZSBjb21tb24gaW4gdGhlIExvdyBhbmQgTWVkaXVtIGluY29tZSBncm91cHMgYW5kIGluZGljYXRlcyBzb21lIHZhcmlhYmlsaXR5IGluIHRoZSB0aGUgZGlhYmV0aWMgZ3JvdXAuIFNpbWlsYXIgcGF0dGVybnMgd2VyZSBvYnNlcnZlZCBhbW9uZyBnZW5lcmFsIGhlYWx0aCBzdGF0dXMgd2l0aCB0aG9zZSBpbiB0aGUgcG9vciBoZWFsdGggc3RhdHVzIGFsc28gd2l0aCBoaWdoZXIgQk1JIGJvdGggaW4gdGhlIGRpYWJldGljIGFuZCBub24tZGlhYmV0aWMgZ3JvdXBzLiBUaGUgc2hpZnQgaW4gcGVha3MgaW4gYm90aCBkZW5zaXR5IHBsb3RzIHN1Z2dlc3RzIGFzc29jaWF0aW9ucyBiZXR3ZWVuIGRpYWJldGVzIGFuZCBCTUkgd2hpY2ggZGlmZmVycyBhbW9uZyBkaWZmZXJlbnQgaW5jb21lIGFuZCBoZWFsdGggZ3JvdXBzLiAKCgo=